Advertisement
Guest User

Untitled

a guest
Mar 19th, 2017
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.31 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.  
  11. #include <SPI.h>
  12. #include "RF24.h"
  13.  
  14.  
  15. // 12 possible bytes for now.. Always send one more byte than the receiver awaits, for some reason.. Otherwise it doesn't work!?
  16. uint8_t dataPackage[12];
  17.  
  18. // the raw input values, analogRead will be stored in those.
  19. int raw_X, raw_Y, raw_RX, raw_RY = 512;
  20.  
  21. // speed range, use three possible speed ranges for finer control
  22. byte drive_speedRanges[] = {100, 50, 0};
  23. byte drive_curSpeedRange = 2;
  24.  
  25. int final_X, final_RY = 512;
  26.  
  27. //
  28. // 0 - 255
  29. // 50 - 205
  30. // 100 - 155
  31.  
  32. // byte to store the raw adress values in
  33. byte raw_address = 0;
  34. // byte to store the raw values of up to 16 buttons
  35. byte raw_buttonByte1, raw_buttonByte2 = 0;
  36.  
  37. // analogRead value for the 6 buttons
  38. int anRead = 0;
  39.  
  40. // final state (on/off of the buttons) and the variables needet for software debounce
  41. byte final_buttonByte1, final_buttonByte2 = 0;
  42. byte lastButtonOnTime1[8];
  43. byte lastButtonOnTime2[8];
  44. byte lastFinal_buttonByte1, lastFinal_buttonByte2;
  45.  
  46.  
  47. int dt = 0;
  48. int lastMillis = 0;
  49.  
  50. // initialize the RF24 library. Pin 9 and 10 are used for CE and CSN.
  51. RF24 radio(9, 10);
  52.  
  53. // Most codes use some crazy 64 bit long weird number as a pipe. But "1" works just fine..
  54. const uint64_t pipe = 1;
  55.  
  56.  
  57. void setup() {
  58.   // serial is only used for debugging. Uncomment if no debugging is needed.
  59.   Serial.begin(9600);
  60.   // begin radio
  61.   radio.begin();
  62.   // 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)
  63.   radio.setPALevel(RF24_PA_MIN);
  64.   // debug
  65.   Serial.println("started..");
  66.   // open the writing pipe since we are a sender
  67.   radio.openWritingPipe(pipe);
  68.   // debug
  69.   Serial.println("opened..");
  70.  
  71.   pinMode(5, INPUT_PULLUP);
  72.   pinMode(6, INPUT_PULLUP);
  73.   pinMode(7, INPUT_PULLUP);
  74.   pinMode(8, INPUT_PULLUP);
  75.  
  76. }
  77.  
  78. void loop() {
  79.   // delta time, time since last loop
  80.   dt = millis() - lastMillis;
  81.   lastMillis = millis();
  82.  
  83.  
  84.   // read the 4 analog values and save them in the variables
  85.   raw_X = analogRead(1);
  86.   raw_Y = analogRead(0);
  87.   raw_RX = analogRead(3);
  88.   raw_RY = analogRead(2);
  89.  
  90.   // 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
  91.   // 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
  92.   // difference between raw and final value is the faster the servo/motor accelerates
  93.   // change the following two values to adjust, the lower the value the quicker the final value will follow the raw value.
  94.   #define steeringInertiaValue 6;
  95.   #define drivingInertialValue 9;
  96.   // steering:
  97.   if (raw_X >= final_X) // if the raw value is lower than the final value
  98.   {
  99.     int diff = raw_X - final_X; // get the difference between both values
  100.     diff = diff / steeringInertiaValue; // the difference gets divided by the "inertia value"
  101.     min(final_X = final_X + diff, raw_X); // now the difference is added to the final value
  102.    
  103.  }
  104.   else if (raw_X <= final_X) // this is pretty much the same as the above just in the other direction
  105.   {
  106.     int diff = final_X - raw_X;
  107.     diff = diff / steeringInertiaValue;
  108.     max(final_X = final_X -diff, raw_X);
  109.    
  110.   }
  111.   // driving:
  112.   if (raw_RY >= final_RY)
  113.   {
  114.     int diff = raw_RY - final_RY;
  115.     diff = diff / drivingInertialValue;
  116.     min(final_RY = final_RY + diff, raw_RY);
  117.    
  118.  }
  119.   else if (raw_RY <= final_RY)
  120.   {
  121.     int diff = final_RY - raw_RY;
  122.     diff = diff / drivingInertialValue;
  123.     max(final_RY = final_RY -diff, raw_RY);
  124.    
  125.   }
  126.   //
  127.  
  128.   // debug
  129.   Serial.println(final_X);
  130.  
  131.   // map the raw values and store them in the dataPackage
  132.   dataPackage[1] = map(final_X, 0, 1023, 0, 255);
  133.   dataPackage[2] = map(raw_Y, 0, 1023, 0, 255);
  134.   dataPackage[3] = map(raw_RX, 0, 1023, 0, 255);
  135.   dataPackage[4] = map(final_RY, 0, 1023, 0 + drive_speedRanges[drive_curSpeedRange], 255 - drive_speedRanges[drive_curSpeedRange]);
  136.  
  137.   // get the current adress from the jumpers (pin 5 to 8) and write to the adress byte
  138.   // since they use internal pullup we invert the digitalRead value
  139.   bitWrite(raw_address, 0, !digitalRead(5));
  140.   bitWrite(raw_address, 1, !digitalRead(6));
  141.   bitWrite(raw_address, 2, !digitalRead(7));
  142.   bitWrite(raw_address, 3, !digitalRead(8));
  143.  
  144.   dataPackage[0] = raw_address;
  145.  
  146.   // get the Joystick buttons
  147.   bitWrite(raw_buttonByte1, 0, digitalRead(2));
  148.   bitWrite(raw_buttonByte1, 1, digitalRead(3));
  149.  
  150.   // get 6 buttons from one analog pin using voltage dividers and analog read.
  151.   anRead = analogRead(A7);
  152.  
  153.   if (anRead < 560 && anRead > 490) {
  154.     raw_buttonByte2 = B00000000;
  155.   }
  156.   else if (anRead < 20) {
  157.     raw_buttonByte2 = B00000001;
  158.   }
  159.   else if (anRead < 270 && anRead > 200) {
  160.     raw_buttonByte2 = B00000010;
  161.   }
  162.   else if (anRead < 450 && anRead > 390) {
  163.     raw_buttonByte2 = B00000100;
  164.   }
  165.   else if (anRead < 660 && anRead > 585) {
  166.     raw_buttonByte2 = B00001000;
  167.   }
  168.   else if (anRead < 820 && anRead > 720) {
  169.     raw_buttonByte2 = B00010000;
  170.   }
  171.   else if (anRead > 900) {
  172.     raw_buttonByte2 = B00100000;
  173.   }
  174.  
  175.   // button debouncing for both button bytes and storing them in on/off variables
  176.   for (byte i = 0; i < 8; i++)
  177.   {
  178.     if (bitRead(raw_buttonByte1, i) == HIGH)
  179.     {
  180.       lastButtonOnTime1[i] = lastButtonOnTime1[i] + dt;
  181.       if (lastButtonOnTime1[i] > 200)
  182.       {
  183.         bitWrite(final_buttonByte1, i, !bitRead(final_buttonByte1, i));
  184.         lastButtonOnTime1[i] = 0;
  185.       }
  186.     }
  187.     else
  188.     {
  189.       lastButtonOnTime1[i] = 0;
  190.     }
  191.  
  192.   }
  193.  
  194.   for (byte i = 0; i < 8; i++)
  195.   {
  196.     if (bitRead(raw_buttonByte2, i) == HIGH)
  197.     {
  198.       lastButtonOnTime2[i] = lastButtonOnTime2[i] + dt;
  199.       if (lastButtonOnTime2[i] > 200)
  200.       {
  201.         bitWrite(final_buttonByte2, i, !bitRead(final_buttonByte2, i));
  202.         lastButtonOnTime2[i] = 0;
  203.       }
  204.     }
  205.     else
  206.     {
  207.       lastButtonOnTime2[i] = 0;
  208.     }
  209.  
  210.   }
  211.  
  212.   //
  213.   dataPackage[5] = final_buttonByte1;
  214.   dataPackage[6] = final_buttonByte2;
  215.  
  216.  
  217.   // apply the max speed value change (use least significant bit of buttonByte2 for now)
  218.   if (bitRead(final_buttonByte2, 0) != bitRead(lastFinal_buttonByte2, 0))
  219.   {
  220.     drive_curSpeedRange = drive_curSpeedRange + 1;
  221.     if (drive_curSpeedRange > 2) {
  222.       drive_curSpeedRange = 0;
  223.     }
  224.   }
  225.  
  226.  
  227.   // update the "last" values
  228.   lastFinal_buttonByte1 = final_buttonByte1;
  229.   lastFinal_buttonByte2 = final_buttonByte2;
  230.  
  231.   // send the dataPackage
  232.   radio.write(dataPackage, sizeof(dataPackage));
  233.   //debug
  234.   //Serial.println(final_buttonByte2, BIN);
  235.   //Serial.println(dataPackage[0]);
  236.   //Serial.println(raw_adress);
  237.   // wait for a short amount of time.. Not sure if needed.
  238.   delay(10);
  239.   // debug
  240.  
  241.  
  242.  
  243. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement