Advertisement
Guest User

Untitled

a guest
Nov 19th, 2017
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.25 KB | None | 0 0
  1. // NRF24 based radio controller for radio controlled tractors
  2. // by modelleicher
  3. // NRF24 Library: https://github.com/TMRh20/RF24
  4. // Inspiration by: "RC Tractor Guy" on youtube https://www.youtube.com/user/magicalmachines/videos
  5. // Also great thanks to Antony Cartwright for the best NRF24 tutorial on youtube (bare basics explanation) https://www.youtube.com/watch?v=Qn2YLSYz3WM
  6.  
  7. // work in progress, just a start for now.
  8. // February 2017
  9.  
  10. // edit log: (since November 2017)
  11. // 18/11/2017
  12. // - addition of Z1 and Z2 axis
  13. // - having a switch to turn on/off the inertia simulation
  14. // - power level changed from min to low
  15.  
  16.  
  17. #include <SPI.h>
  18. #include "RF24.h"
  19.  
  20.  
  21. // 12 possible bytes for now.. Always send one more byte than the receiver awaits, for some reason.. Otherwise it doesn't work!?
  22. uint8_t dataPackage[12];
  23.  
  24. // the raw input values, analogRead will be stored in those.
  25. int raw_X, raw_Y, raw_RX, raw_RY, raw_Z1, raw_Z2 = 512;
  26.  
  27. // speed range, use three possible speed ranges for finer control
  28. byte drive_speedRanges[] = {100, 50, 0};
  29. byte drive_curSpeedRange = 2;
  30.  
  31. int final_X, final_RY, final_RX, final_Y = 512;
  32.  
  33.  
  34. //
  35. // 0 - 255
  36. // 50 - 205
  37. // 100 - 155
  38.  
  39. // byte to store the raw adress values in
  40. byte raw_address = 0;
  41. // byte to store the raw values of up to 16 buttons
  42. byte raw_buttonByte1, raw_buttonByte2 = 0;
  43.  
  44. // analogRead value for the 6 buttons
  45. int anRead = 0;
  46.  
  47. // final state (on/off of the buttons) and the variables needet for software debounce
  48. byte final_buttonByte1, final_buttonByte2 = 0;
  49. byte lastButtonOnTime1[8];
  50. byte lastButtonOnTime2[8];
  51. byte lastFinal_buttonByte1, lastFinal_buttonByte2;
  52.  
  53. //
  54. bool inertiaSimulation = true;
  55.  
  56.  
  57. int dt = 0;
  58. int lastMillis = 0;
  59.  
  60. // initialize the RF24 library. Pin 9 and 10 are used for CE and CSN.
  61. RF24 radio(9, 10);
  62.  
  63. // Most codes use some crazy 64 bit long weird number as a pipe. But "1" works just fine..
  64. const uint64_t pipe = 1;
  65.  
  66.  
  67. void setup() {
  68.   // serial is only used for debugging. Uncomment if no debugging is needed.
  69.   Serial.begin(9600);
  70.   // begin radio
  71.   radio.begin();
  72.   // i use PA_MIN for now.. It is good for at least 2m.. Only use higher levels if your power supply can support it and you have a proper Capacitor across the VCC and GND pins on the NRF module. (I suggest at least 100µF)
  73.   radio.setPALevel(RF24_PA_LOW);
  74.   // debug
  75.   Serial.println("started..");
  76.   // open the writing pipe since we are a sender
  77.   radio.openWritingPipe(pipe);
  78.   // debug
  79.   Serial.println("opened..");
  80.  
  81.   pinMode(5, INPUT_PULLUP);
  82.   pinMode(6, INPUT_PULLUP);
  83.   pinMode(7, INPUT_PULLUP);
  84.   pinMode(8, INPUT_PULLUP);
  85.  
  86.   pinMode(4, INPUT_PULLUP);
  87.  
  88.   pinMode(2, INPUT);
  89.   pinMode(3, INPUT);  
  90. }
  91.  
  92. void loop() {
  93.   // delta time, time since last loop
  94.   dt = millis() - lastMillis;
  95.   lastMillis = millis();
  96.  
  97.   // check if inertia simulation is active
  98.   inertiaSimulation = digitalRead(4);
  99.  
  100.  
  101.   // read the 4 analog values and save them in the variables
  102.   raw_X = analogRead(1);
  103.   raw_Y = analogRead(0);
  104.   raw_RX = analogRead(3);
  105.   raw_RY = analogRead(2);
  106.  
  107.   // read the 2 additional analog values for the two pots
  108.   raw_Z1 = analogRead(6);
  109.   raw_Z2 = analogRead(5);
  110.  
  111.   // some very basic inertia simulation so the vehicle doesn't launch forward/backward and to limit the steering speed since the servo with a 2S Lipo is really fast
  112.   // instead of the raw value the final value is sent to the vehicle. The final value is pretty much just a smoothed out version of the raw value. The higher the
  113.   // difference between raw and final value is the faster the servo/motor accelerates
  114.   // change the following two values to adjust, the lower the value the quicker the final value will follow the raw value.
  115.   #define steeringInertiaValue 8;
  116.   #define drivingInertialValue 14;
  117.   if (inertiaSimulation == true)
  118.   {
  119.       // steering:
  120.       if (raw_X >= final_X) // if the raw value is lower than the final value
  121.       {
  122.         int diff = raw_X - final_X; // get the difference between both values
  123.         diff = diff / steeringInertiaValue; // the difference gets divided by the "inertia value"
  124.         min(final_X = final_X + diff, raw_X); // now the difference is added to the final value
  125.        
  126.      }
  127.       else if (raw_X <= final_X) // this is pretty much the same as the above just in the other direction
  128.       {
  129.         int diff = final_X - raw_X;
  130.         diff = diff / steeringInertiaValue;
  131.         max(final_X = final_X -diff, raw_X);
  132.        
  133.       }
  134.       // driving:
  135.       if (raw_RY >= final_RY)
  136.       {
  137.         int diff = raw_RY - final_RY;
  138.         diff = diff / drivingInertialValue;
  139.         min(final_RY = final_RY + diff, raw_RY);
  140.        
  141.      }
  142.       else if (raw_RY <= final_RY)
  143.       {
  144.         int diff = final_RY - raw_RY;
  145.         diff = diff / drivingInertialValue;
  146.         max(final_RY = final_RY -diff, raw_RY);
  147.        
  148.       }
  149.   }
  150.   else
  151.   {
  152.     final_X = raw_X;
  153.     final_RY = raw_RY;
  154.   }
  155.   //
  156.  
  157.   // debug
  158.   Serial.println(final_X);
  159.  
  160.   // map the raw values and store them in the dataPackage
  161.   // drive controls
  162.   dataPackage[1] = map(final_X, 0, 1023, 0, 255);
  163.   dataPackage[4] = map(final_RY, 0, 1023, 0 + drive_speedRanges[drive_curSpeedRange], 255 - drive_speedRanges[drive_curSpeedRange]);
  164.   // other controls
  165.   dataPackage[2] = map(final_Y, 0, 1023, 0, 255);
  166.   dataPackage[3] = map(raw_RX, 0, 1023, 0, 255);
  167.  
  168.   // get the current adress from the jumpers (pin 5 to 8) and write to the adress byte
  169.   // since they use internal pullup we invert the digitalRead value
  170.   bitWrite(raw_address, 0, !digitalRead(5));
  171.   bitWrite(raw_address, 1, !digitalRead(6));
  172.   bitWrite(raw_address, 2, !digitalRead(7));
  173.   bitWrite(raw_address, 3, !digitalRead(8));
  174.  
  175.   dataPackage[0] = raw_address;
  176.   // debug
  177.   Serial.println(raw_address);
  178.  
  179.   // get the Joystick buttons
  180.   bitWrite(raw_buttonByte1, 0, digitalRead(2));
  181.   bitWrite(raw_buttonByte1, 1, digitalRead(3));
  182.  
  183.   // get 6 buttons from one analog pin using voltage dividers and analog read.
  184.   anRead = analogRead(A7);
  185.  
  186.   if (anRead < 560 && anRead > 490) {
  187.     raw_buttonByte2 = B00000000;
  188.   }
  189.   else if (anRead < 20) {
  190.     raw_buttonByte2 = B00000001;
  191.   }
  192.   else if (anRead < 270 && anRead > 200) {
  193.     raw_buttonByte2 = B00000010;
  194.   }
  195.   else if (anRead < 450 && anRead > 390) {
  196.     raw_buttonByte2 = B00000100;
  197.   }
  198.   else if (anRead < 660 && anRead > 585) {
  199.     raw_buttonByte2 = B00001000;
  200.   }
  201.   else if (anRead < 820 && anRead > 720) {
  202.     raw_buttonByte2 = B00010000;
  203.   }
  204.   else if (anRead > 900) {
  205.     raw_buttonByte2 = B00100000;
  206.   }
  207.  
  208.   // button debouncing for both button bytes and storing them in on/off variables
  209.   for (byte i = 0; i < 8; i++)
  210.   {
  211.     if (bitRead(raw_buttonByte1, i) == HIGH)
  212.     {
  213.       lastButtonOnTime1[i] = lastButtonOnTime1[i] + dt;
  214.       if (lastButtonOnTime1[i] > 200)
  215.       {
  216.         bitWrite(final_buttonByte1, i, !bitRead(final_buttonByte1, i));
  217.         lastButtonOnTime1[i] = 0;
  218.       }
  219.     }
  220.     else
  221.     {
  222.       lastButtonOnTime1[i] = 0;
  223.     }
  224.  
  225.   }
  226.  
  227.   for (byte i = 0; i < 8; i++)
  228.   {
  229.     if (bitRead(raw_buttonByte2, i) == HIGH)
  230.     {
  231.       lastButtonOnTime2[i] = lastButtonOnTime2[i] + dt;
  232.       if (lastButtonOnTime2[i] > 200)
  233.       {
  234.         bitWrite(final_buttonByte2, i, !bitRead(final_buttonByte2, i));
  235.         lastButtonOnTime2[i] = 0;
  236.       }
  237.     }
  238.     else
  239.     {
  240.       lastButtonOnTime2[i] = 0;
  241.     }
  242.  
  243.   }
  244.  
  245.   //
  246.   dataPackage[5] = final_buttonByte1;
  247.   dataPackage[6] = final_buttonByte2;
  248.  
  249.   dataPackage[7] = map(raw_Z1, 0, 1023, 0, 255);  
  250.   dataPackage[8] = map(raw_Z2, 0, 1023, 0, 255);  
  251.  
  252.   // apply the max speed value change (use least significant bit of buttonByte2 for now)
  253.   if (bitRead(final_buttonByte2, 0) != bitRead(lastFinal_buttonByte2, 0))
  254.   {
  255.     drive_curSpeedRange = drive_curSpeedRange + 1;
  256.     if (drive_curSpeedRange > 2) {
  257.       drive_curSpeedRange = 0;
  258.     }
  259.   }
  260.  
  261.  
  262.   // update the "last" values
  263.   lastFinal_buttonByte1 = final_buttonByte1;
  264.   lastFinal_buttonByte2 = final_buttonByte2;
  265.  
  266.   // send the dataPackage
  267.   radio.write(dataPackage, sizeof(dataPackage));
  268.   //debug
  269.   //Serial.println(final_buttonByte2, BIN);
  270.   //Serial.println(dataPackage[0]);
  271.   //Serial.println(raw_adress);
  272.   // wait for a short amount of time.. Not sure if needed.
  273.   delay(10);
  274.   // debug
  275.  
  276.  
  277.  
  278. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement