Advertisement
Guest User

Untitled

a guest
Mar 19th, 2017
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.43 KB | None | 0 0
  1. // NRF24 based radio receiver 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. // March 2017
  9.  
  10.  
  11.  
  12. #include <SPI.h>
  13. #include "RF24.h"
  14.  
  15. #include <Servo.h>
  16.  
  17. // defining all the pins, change pins here if you use different pinout!
  18. #define PIN_driveMotor_dir1  5
  19. #define PIN_driveMotor_dir2  4
  20. #define PIN_driveMotor_pwm  3
  21.  
  22. #define PIN_steering_servo  7
  23.  
  24. #define PIN_lights_lowBeam  8
  25.  
  26. #define PIN_batt_readVcc  A0
  27.  
  28. // all the settings for deadzone on motor and limits on servos
  29. #define SET_driveMotor_deadZoneMax  132
  30. #define SET_driveMotor_deadZoneMin  124
  31.  
  32. // steering trim on Deutz D16006 - min 50 max 120
  33. #define SET_steering_servoMin  50
  34. #define SET_steering_servoMax  120
  35.  
  36.  
  37.  
  38. // right now we are only receiving 6 bytes..
  39. uint8_t dataPackage[7];
  40. // dataPackage[0] = adress
  41. // dataPackage[1] = steering (X Axis)
  42. // dataPackage[2] = lifting arms (Y Axis)
  43. // dataPackage[3] = lifting arms 2 (RX Axis)
  44. // dataPackage[4] = driving (RY Axis)
  45. // dataPackage[5] = 8 Buttons (2 Joystick Buttons and 6 unused)
  46. // dataPackage[6] = 8 more buttons (6 lights/general buttons and 2 unused)
  47.  
  48. // initialize the RF24
  49. RF24 radio(9, 10);
  50.  
  51. // again, the pipe. Important, Sender and Receiver have to use the same, obviously.
  52. const uint64_t pipe = 1;
  53.  
  54. // address
  55. byte address = B00000001;
  56.  
  57. // battery voltage reading
  58. int batt_internalVCC = 0;
  59. int batt_rawAnalogRead = 0;
  60. int batt_milisecondsLow = 0;
  61.  
  62. // not used yet
  63. int dt = 0;
  64. int lastMillis = 0;
  65.  
  66. // initialize the steering servo
  67. Servo servo1;
  68.  
  69. void setup() {
  70.   // serial for debug
  71.   Serial.begin(9600);
  72.   // begin radio
  73.   radio.begin();
  74.   // no need to set PA level anything higher than min as long as the communication is only one way.
  75.   radio.setPALevel(RF24_PA_MIN);
  76.   // debug
  77.   Serial.println("started..");
  78.   // since we are the receiver, open a reading pipe
  79.   radio.openReadingPipe(1, pipe);
  80.   // debug
  81.   Serial.println("opened..");
  82.   // start listening (now we are a receiver and listening for packets)
  83.   radio.startListening();
  84.   //debug
  85.   Serial.println("listening..");
  86.  
  87.   // attach the steering servo at pin 7
  88.   servo1.attach(PIN_steering_servo);
  89.  
  90.   //
  91.   pinMode(PIN_lights_lowBeam, OUTPUT);
  92.   digitalWrite(PIN_lights_lowBeam, LOW);
  93. }
  94.  
  95. void loop() {
  96.   // not used yet
  97.   dt = millis() - lastMillis;
  98.   lastMillis = millis();
  99.  
  100.   // check if there are packets received. radio.availiable() will return true if there is anything in the buffer
  101.   if (radio.available())
  102.   {
  103.     //read the data and store in dataPackage array.
  104.     radio.read(dataPackage, sizeof(dataPackage));
  105.  
  106.     // check if the address matches ours
  107.     if (dataPackage[0] == address)
  108.     {
  109.      
  110.    
  111.         // current array index to axis:
  112.         // 1 = X
  113.         // 2 = Y
  114.         // 3 = RX
  115.         // 4 = RY
  116.    
  117.         // control drive motor
  118.         if (dataPackage[4] > SET_driveMotor_deadZoneMax) // larger than 130 -> forwards
  119.         {
  120.             analogWrite(PIN_driveMotor_pwm, map(dataPackage[4], SET_driveMotor_deadZoneMax, 255, 0, 255)); // write the PWM value
  121.             // set direction:
  122.             digitalWrite(PIN_driveMotor_dir1, HIGH);
  123.             digitalWrite(PIN_driveMotor_dir2, LOW);
  124.         }
  125.         else if (dataPackage[4] < SET_driveMotor_deadZoneMin) // smaller than 120 -> backwards
  126.         {
  127.             analogWrite(PIN_driveMotor_pwm, map(dataPackage[4], SET_driveMotor_deadZoneMin, 0, 0, 255)); // write PWM value
  128.             // set direction:
  129.             digitalWrite(PIN_driveMotor_dir1, LOW);
  130.             digitalWrite(PIN_driveMotor_dir2, HIGH);      
  131.         }
  132.         else // stop driving
  133.         {
  134.             analogWrite(PIN_driveMotor_pwm, 0);
  135.             digitalWrite(PIN_driveMotor_dir1, LOW);
  136.             digitalWrite(PIN_driveMotor_dir2, LOW);    
  137.         }
  138.  
  139.    
  140.        
  141.         // map the steering value to servo min/max values
  142.         dataPackage[1] = map(dataPackage[1], 0, 255, SET_steering_servoMin, SET_steering_servoMax);
  143.         // set the servo value
  144.         servo1.write(dataPackage[1]);  
  145.  
  146.        
  147.  
  148.         // light
  149.         digitalWrite(PIN_lights_lowBeam, bitRead(dataPackage[6], 3));
  150.  
  151.        
  152.  
  153.  
  154.     // debug
  155.     //Serial.println(dataPackage[1]);
  156.     //Serial.println(dataPackage[2]);
  157.     //Serial.println(dataPackage[3]);    
  158.     //Serial.println("----------------------");    
  159.     }
  160.   }
  161.   else
  162.   {
  163.      // this is called each time the loop runs and there is no data in the buffer from the NRF24
  164.   }
  165.  
  166.  
  167.   // check the battery voltage to not over discharge the lipo cells!
  168.   checkBatteryVoltage(dt);
  169.      
  170.  
  171.  
  172.   // not sure if the dalay is needet.
  173.   delay(10);
  174.  
  175.  
  176.  
  177. }
  178.  
  179. void checkBatteryVoltage(int dt)
  180. {
  181.          // since LiPo cells can take damage or even explove if over-discharged we need to monitor the voltage
  182.         // some LiPo cells come with protection circuits on the cell itself, but the cheap ones i use don't.
  183.         // also most multiple cell lipos dont. I use a 2S Lipo in this tractor.
  184.         // so we read the current battery voltage with analogRead and a voltage divider since the arduino runs on 3.3V and the LiPo fully charged has 8.4V
  185.         // My Arduino runs on 3.27V usually, that means that our lower limit of 6.6V is reached at a analogRead value of 687
  186.         // I did want to take the internal voltage into account but floating point math isn't that great on the arduino, and since i had a conservative number for the lower limit i think we'll be fine.
  187.         // you need to change this whole thing if you are not running the arduino off of a 3.3V regulator!!!
  188.        
  189.         //batt_internalVCC = getVCCReading();
  190.        
  191.         batt_rawAnalogRead = analogRead(PIN_batt_readVcc);
  192.         if (batt_rawAnalogRead <= 687)
  193.         {
  194.              Serial.println(batt_milisecondsLow);
  195.             batt_milisecondsLow = batt_milisecondsLow + dt;
  196.             if (batt_milisecondsLow > 1000) // battery is low for more than 1 second (to avoid shutting off on current spikes)
  197.             {
  198.                 goBlinkLowBatteryLights(); // blink the lights really fast to show that the battery is empty
  199.                 batt_milisecondsLow = 0; // reset the battery low timer.. So the lights will start again after 1 second until battery is changed
  200.             }
  201.         }
  202.         else
  203.         {
  204.             batt_milisecondsLow = 0;
  205.         }
  206.         //Serial.println(batt_rawAnalogRead);
  207. }
  208.  
  209. void goBlinkLowBatteryLights()
  210. {
  211.  
  212.     digitalWrite(PIN_lights_lowBeam, HIGH);
  213.     delay(50);
  214.     digitalWrite(PIN_lights_lowBeam, LOW);
  215.     delay(250);
  216.     digitalWrite(PIN_lights_lowBeam, HIGH);
  217.     delay(50);
  218.     digitalWrite(PIN_lights_lowBeam, LOW);
  219.     delay(250);    
  220. }
  221.  
  222. // from RCTractorGuy Library, not used right now since i can't get the floating point stuff to work properly
  223. long getVCCReading(){
  224.   long result;
  225.   // Read 1.1V reference against AVcc
  226.   ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  227.   delay(2); // Wait for Vref to settle
  228.   ADCSRA |= _BV(ADSC); // Convert
  229.   while (bit_is_set(ADCSRA,ADSC));
  230.   result = ADCL;
  231.   result |= ADCH<<8;
  232.   result = (1126400L / result); // Back-calculate AVcc in mV
  233.   return result;
  234. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement