It’s been a long time since anyone has worked on the RC Car project here in the Workshop and since I’m new to this project I figured now is a great time to begin simplifying and streamlining the wiring. The way everything was wired previously was great for prototyping but it left something to be desired for a more polished product. A lot of the wiring had gotten messed up from moving the bikes and just leaving the project unused for so long, so I grabbed a multimeter and began the work by checking all the connections. Previously a breadboard was used to send power to the bikes and also serve as a hub point to read the data from. This created a mess of wires that made it difficult to see how things connect and so I soldered up all the power lines and ground lines and added on a male pin. Now they can be directly connected to the 5v and GND pins on the Arduino itself. I then added male pins to each of the three signal wires so that they too could be plugged directly into the Arduino. With this new setup, I could eliminate the breadboard which cleaned up things nicely. Now that the connections were simplified I verified that everything was working and turned my attention to the RC car itself. When I began working on the car nothing seemed to be responsive. So, I decided to dissemble the system and redo it, following the same guidelines used previously, which fixed the issues. Now both Arduinos are communicating correctly and everything seems to be working except for the throttle which is glitchy at best. Once the receiver side is fully functional I’ll streamline the wiring and clean it up. Things on the to-do list for this project now are:
- Fix Throttle response
- Clean wiring on receiver side
- Add buttons to enable reverse mode
- Reimplement the FPV system
Once all these are done I’ll be designing a PCB that will condense everything and make the project more professional. Below you’ll find the current versions of the code being used on the project.
-Andrew
#include <Adafruit_9DOF.h>#include <Adafruit_L3GD20_U.h>#include <Adafruit_LSM303_U.h>#include <Adafruit_Sensor.h>#include <Wire.h>#include <SPI.h> //SPI library to communicate with the nRF24+#include "RF24.h" // Download and Install (See above)#include "printf.h" // Needed for "printDetails" Takes up some memory#define CE_PIN 7 // The pins to be used for CE and SN#define CSN_PIN 8/* Assign a unique ID to the sensors */Adafruit_9DOF dof = Adafruit_9DOF();Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(30301);Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(30302);RF24 radio(CE_PIN, CSN_PIN);byte addresses[][6] = {"1Node", "2Node"}; // These will be the names of the "Pipes"unsigned long timeNow; // Used to grab the current time, calculate delaysunsigned long started_waiting_at;boolean timeout; // Timeout? True or False// Allows testing of radios and code without Joystick hardware. Set 'true' when joystick connected//boolean hasHardware = false;boolean hasHardware = true;struct dataStruct {unsigned long _micros; // to save response timesint throttle; //int handBreak;int bikeTilt;int alignment; //steering trimint headpitch; //pitch of the camera mountint headroll; //roll of camera mountint heading; //yaw of the camera mountbool ModeSwitch; // centering switch} myData; // This can be accessed in the form: myData.Xposition etc.void setup() /****** SETUP: RUNS ONCE ******/{Serial.begin(115200);Serial.println(F("Lets send this data"));printf_begin(); //uncomment for debug infopinMode(6, INPUT); // switch for drive modepinMode(4, INPUT); //the radio channel switchpinMode(9, OUTPUT); // power led/* Initialise the sensors */accel.begin();mag.begin();radio.begin(); // Initialize the nRF24L01 Radioif (digitalRead(4) == HIGH){radio.setChannel(106); // set to channel 1}else{radio.setChannel(120); // set to channel 2}radio.setDataRate(RF24_250KBPS);// Set the Power Amplifier Level low to prevent power supply related issues since this is a// getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.// PALevelcan be one of four levels: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAXradio.setPALevel(RF24_PA_HIGH);// radio.setPALevel(RF24_PA_MAX);// Open a writing and reading pipe on each radio, with opposite addressesradio.openWritingPipe(addresses[0]);radio.openReadingPipe(1, addresses[1]);// Start the radio listening for dataradio.startListening();radio.printDetails(); //Uncomment to show debugging information}void loop() /****** LOOP: RUNS CONSTANTLY ******/{digitalWrite(9, HIGH); //turn on the power ledsensors_event_t accel_event;sensors_event_t mag_event;sensors_vec_t orientation;accel.getEvent(&accel_event);mag.getEvent(&mag_event);radio.stopListening(); // First, stop listening so we can talk.if (hasHardware) // Set in variables at top{myData.throttle = analogRead(A0);myData.alignment = analogRead(A1);myData.handBreak = analogRead(A2);myData.bikeTilt = analogRead(A3);myData.ModeSwitch = digitalRead(6);myData.headroll = orientation.roll;myData.headpitch = orientation.pitch;myData.heading = orientation.heading;}//else{// myData.Lposition = 256; // Send some known fake data// myData.Rposition = 512;}myData._micros = micros(); // Send back for timingSerial.print("Throttle = ");Serial.print(myData.throttle);Serial.print("\t");Serial.print("Hand Break = ");Serial.print(myData.handBreak);Serial.print("\t");Serial.print("Bike Tilt = ");Serial.print(myData.bikeTilt);Serial.print("\t");Serial.print(myData.heading);Serial.print("\t");Serial.println(myData.headpitch);Serial.print(F("Now sending - "));if (!radio.write( &myData, sizeof(myData) )) {Serial.println(F("Transmit failed "));}radio.startListening();started_waiting_at = micros(); // timeout period, get the current microsecondstimeout = false; // variable to indicate if a response was received or notwhile ( ! radio.available() ) {if (micros() - started_waiting_at > 200000 ) { // If waited longer than 200ms, indicate timeout and exit while looptimeout = true;break;}}if ( timeout ){ // Describe the resultsSerial.println(F("Response timed out - no Acknowledge."));}else{// Grab the response, compare, and send to Serial Monitorradio.read( &myData, sizeof(myData) );timeNow = micros();digitalWrite(2, HIGH);// Show itSerial.print(F("Sent "));Serial.print(timeNow);Serial.print(F(", Got response "));Serial.print(myData._micros);Serial.print(F(", Round-trip delay "));Serial.print(timeNow - myData._micros);Serial.println(F(" microseconds "));}// Send again after delay. When working OK, change to something like 100delay(100);}void initSensors(){if(!accel.begin()){/* There was a problem detecting the LSM303 ... check your connections *///Serial.println(F("Ooops, no LSM303 detected ... Check your wiring!"));}elseSerial.println("Somethings wrong");if(!mag.begin()){/* There was a problem detecting the LSM303 ... check your connections */Serial.println("Ooops, no LSM303 detected ... Check your wiring!");}elseSerial.println("Somethings off");}RECIEVER CODE:#include <SoftwareServo.h>#include <SPI.h>#include "RF24.h"#define CE_PIN 7 // The pins to be used for CE and SN#define CSN_PIN 8RF24 radio(CE_PIN, CSN_PIN);SoftwareServo steering;SoftwareServo gogojuice;SoftwareServo yaw;SoftwareServo pitch;SoftwareServo roll;byte addresses[][6] = {"1Node", "2Node"}; // These will be the names of the "Pipes"struct dataStruct {unsigned long _micros;int throttle; // The Joystick position valuesint handBreak;int bikeTilt;int alignment;int headpitch;int headroll;int heading;bool ModeSwitch;} myData; // This can be accessed in the form: myData.Xposition etc.void setup(){Serial.begin(115200);pinMode(2, OUTPUT);pinMode(3, OUTPUT);pinMode(5, OUTPUT);pinMode(9, OUTPUT); //yawpinMode(6, OUTPUT); //PitchpinMode(10, OUTPUT); //Roll// if (digitalRead(4) == HIGH)// {// radio.setChannel(106); // set to channel 1// }// else// {// radio.setChannel(120); // set to channel 2// }//radio.begin(); // Initialize the nRF24L01 Radioradio.setChannel(108);radio.setDataRate(RF24_250KBPS);radio.setPALevel(RF24_PA_HIGH);// Open a writing and reading pipe on each radio, with opposite addressesradio.openWritingPipe(addresses[1]);radio.openReadingPipe(1, addresses[0]);// Start the radio listening for dataradio.startListening();steering.attach(3);gogojuice.attach(5);yaw.attach(9);pitch.attach(6);roll.attach(10);gogojuice.write(40);Serial.println("Setup Ran");}void loop(){digitalWrite(2,HIGH);if ( radio.available()){while (radio.available()) // While there is data ready to be retrieved from the receive pipe{radio.read( &myData, sizeof(myData) ); // Get the data}radio.stopListening(); // First stop listening so we can transmitradio.write( &myData, sizeof(myData) ); // Send the received data back.radio.startListening(); // Now resume listening so we catch the next packet}double Mode = 0;// if (true == myData.ModeSwitch)// {// Mode = 0.01;// }// else// {// Mode = 0;// }SoftwareServo::refresh();int drive;int offset = myData.alignment;offset = map(offset, 0, 1023, -30, 30);int bikeTiltRecieved = myData.bikeTilt;int handBreakRecieved = myData.handBreak;int throttleRecieved = myData.throttle;int tilt = map(bikeTiltRecieved, 0, 1023, 0, 180);tilt = tilt + offset;if (throttleRecieved > 100 && handBreakRecieved < 100){drive = 96 + throttleRecieved*Mode;//drive = 96 + throttleRecieved;}if (throttleRecieved < 100 && handBreakRecieved > 100){drive = 85;//drive = 85 + throttleRecieved;}if (throttleRecieved > 100 && handBreakRecieved > 100){drive = 90;//drive = 96 + throttleRecieved;}if (throttleRecieved < 100 && handBreakRecieved < 100){drive = 90;//drive = 96 + throttleRecieved;}int PITCH = map (myData.headpitch, -180, 180, 0, 180);int YAW = map(myData.heading, 0, 360, 0, 180);steering.write(tilt);gogojuice.write(drive);yaw.write(YAW);pitch.write(PITCH);roll.write(90);Serial.print("Throttle = ");Serial.print(myData.throttle);Serial.print("\t");Serial.print("Hand Break = ");Serial.print(myData.handBreak);Serial.print("\t");Serial.print("Bike Tilt = ");Serial.print(myData.bikeTilt);Serial.print("\t");Serial.print(YAW);Serial.print("\t");Serial.println(PITCH);}
No comments:
Post a Comment