diff --git a/FoxRC_bt_btn/FoxRC_bt_btn.ino b/FoxRC_bt_btn/FoxRC_bt_btn.ino new file mode 100644 index 0000000..31fafcc --- /dev/null +++ b/FoxRC_bt_btn/FoxRC_bt_btn.ino @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#define RADIO_CHANNEL 42 +#define RADIO_RATE RF24_250KBPS //RF24_1MBPS +#define RADIO_POWER RF24_PA_MAX +#define RADIO_CE 9 +#define RADIO_CSN 10 + +const bool DEBUG = false; + +const int gLedPin = 13; +const int gRxPin = 5; +const int gTxPin = 6; + +const uint8_t pipe[6] = "Foxy1"; // radio address +RF24 radio(RADIO_CE, RADIO_CSN); + +SoftwareSerial BTSerial(gRxPin, gTxPin); + +bool input_lock = 0; +byte drive = 0; + +struct Package { + byte steering; // 0 - off, 1 - turn left, 2 - turn right + byte drive; // 0 - full, 1 - back, 2 - front | same type as uint8_t + bool direction; // false - forward, true - backward + uint8_t speed; // int number 0-255 +}; + +bool send_package(Package* pkg, int size) { + radio.write(pkg, size); + return 1; // loook what is this +} + +bool Broadcast(Package pkg) { + Package pack = pkg; + return send_package(&pack, sizeof(pack)); +} + +Package buildPack(uint8_t speed, byte steering, bool direction) { + Package pack; + pack.speed = speed; + pack.steering = steering; + pack.direction = direction; + pack.drive = drive; + return pack; +} + +void setup() { + BTSerial.begin(9600); + BTSerial.setTimeout(2); + if (DEBUG) { + Serial.begin(9600); + while (!Serial) { + ; + } + Serial.println("Serial is listening..."); + } + + radio.begin(); + radio.setChannel(RADIO_CHANNEL); + radio.setDataRate(RADIO_RATE); + radio.setPALevel(RADIO_POWER); + radio.openWritingPipe(pipe); + radio.setAutoAck(false); + radio.powerUp(); + radio.stopListening(); +} + +void loop() { + if (BTSerial.available()) { + String stickInfo = BTSerial.readStringUntil('\n'); + Serial.println(stickInfo); + if (stickInfo.length() != 8) { + if (DEBUG) { + Serial.print("Error: invalid bluetooth input: "); + Serial.println(stickInfo); + } + return; + } + int angle = stickInfo.substring(0,3).toInt(); + uint8_t speed = map(stickInfo.substring(3,6).toInt(), 0, 100, 0, 255); + uint8_t button = stickInfo.substring(6).toInt(); // 1 - X, 2 - O, 3 - triangle, 4 - square + + if (button == 1) { + input_lock = !input_lock; + if (DEBUG) { + Serial.print("Input Lock status: "); + Serial.println(input_lock); + } + } + + if (input_lock) { + if (DEBUG) { + Serial.println("Input Lock!"); + } + return; + } + + if (button == 3) { + drive++; + if (drive > 2) { + drive = 0; + } + if (DEBUG) { + Serial.print("Drive mode set to "); + Serial.println(drive); + } + } + + byte steering = 0; + if (button != 1 && button != 3) { // 0 is default position that should set steering to 0 + if (button == 2) { + steering = 2; + } else if (button == 4) { + steering = 1; + } + } + + if (DEBUG) { + Serial.println(steering); + } + + bool direction = 0; + if (angle > 180) { + direction = 1; + } + + Package pack = buildPack(speed, steering, direction); + bool sent = Broadcast(pack); + if (DEBUG && sent) { + Serial.print("Package is sent: "); + Serial.println(stickInfo); + } + } +} diff --git a/FoxRC_car_bt/FoxRC_car_bt.ino b/FoxRC_car_bt/FoxRC_car_bt.ino new file mode 100644 index 0000000..bbc00a8 --- /dev/null +++ b/FoxRC_car_bt/FoxRC_car_bt.ino @@ -0,0 +1,172 @@ +#include +#include +#define RADIO_CHANNEL 42 +#define RADIO_RATE RF24_250KBPS //RF24_1MBPS +#define RADIO_POWER RF24_PA_MAX +#define RADIO_CE 7 +#define RADIO_CSN 8 + +#define MOTOR1_MAIN1 5 +#define MOTOR1_MAIN2 6 +#define MOTOR2_MAIN1 9 +#define MOTOR2_MAIN2 10 +#define MOTOR_WHEEL1 A1 +#define MOTOR_WHEEL2 A2 + +const bool DEBUG = false; + +const uint8_t pipe[6] = "Foxy1"; +RF24 radio(RADIO_CE, RADIO_CSN); + +struct Package { + byte steering; // 0 - off, 1 - turn left, 2 - turn right + byte drive; // 0 - full, 1 - back, 2 - front | same type as uint8_t + bool direction; // false - forward, true - backward + uint8_t speed; // int number 0-255 +}; + +bool emergency = false; +int emergencyTimer = 1000; +unsigned long emergencyCounter = 0; + +bool handleEmergency() { + if (!emergency) { + return false; + } + if (DEBUG) { + Serial.println("Emergency lock!"); + } + analogWrite(MOTOR1_MAIN1, 0); + analogWrite(MOTOR1_MAIN2, 0); + analogWrite(MOTOR2_MAIN1, 0); + analogWrite(MOTOR2_MAIN2, 0); + digitalWrite(MOTOR_WHEEL1, LOW); + digitalWrite(MOTOR_WHEEL2, LOW); + return true; +} + +void handleMotors(uint8_t speed, byte steering, byte drive, bool direction) { + switch(drive) { + case(0): { // full drive + switch(direction) { + case(false): { // forward + analogWrite(MOTOR1_MAIN1, 0); + analogWrite(MOTOR1_MAIN2, speed); + analogWrite(MOTOR2_MAIN1, 0); + analogWrite(MOTOR2_MAIN2, speed); + break; + } + case(true): { // backward + analogWrite(MOTOR1_MAIN1, speed); + analogWrite(MOTOR1_MAIN2, 0); + analogWrite(MOTOR2_MAIN1, speed); + analogWrite(MOTOR2_MAIN2, 0); + break; + } + } + break; + } + case(1): { // back drive + switch(direction) { + case(false): { // forward + analogWrite(MOTOR1_MAIN1, 0); + analogWrite(MOTOR1_MAIN2, speed); + break; + } + case(true): { // backward + analogWrite(MOTOR1_MAIN1, speed); + analogWrite(MOTOR1_MAIN2, 0); + break; + } + } + break; + } + case(2): { // front drive + switch(direction) { + case(false): { // forward + analogWrite(MOTOR2_MAIN1, 0); + analogWrite(MOTOR2_MAIN2, speed); + break; + } + case(true): { // backward + analogWrite(MOTOR2_MAIN1, speed); + analogWrite(MOTOR2_MAIN2, 0); + break; + } + } + break; + } + } + + switch(steering) { + case(0): { // off + digitalWrite(MOTOR_WHEEL1, LOW); + digitalWrite(MOTOR_WHEEL2, LOW); + break; + } + case(1): { // turn left + digitalWrite(MOTOR_WHEEL2, HIGH); + digitalWrite(MOTOR_WHEEL1, LOW); + break; + } + case(2): { // turn right + digitalWrite(MOTOR_WHEEL1, HIGH); + digitalWrite(MOTOR_WHEEL2, LOW); + break; + } + } +} + +void setup() { + if (DEBUG) { + Serial.begin(9600); + while (!Serial) { + ; + } + Serial.println("Serial is listening..."); + } + + pinMode(MOTOR_WHEEL1, OUTPUT); + pinMode(MOTOR_WHEEL2, OUTPUT); + digitalWrite(MOTOR_WHEEL1, LOW); + digitalWrite(MOTOR_WHEEL2, LOW); + + radio.begin(); + radio.setChannel(RADIO_CHANNEL); + radio.setDataRate(RADIO_RATE); + radio.setPALevel(RADIO_POWER); + radio.openReadingPipe(1, pipe); + radio.setAutoAck(false); + radio.powerUp(); + radio.startListening(); + + emergencyCounter = millis(); +} + +void loop() { + if (millis() - emergencyCounter > emergencyTimer) { + emergency = true; + } + + if(radio.available()){ + if (emergency) { + emergency = false; + } + emergencyCounter = millis(); + Package pack; + radio.read(&pack, sizeof(pack)); + handleMotors(pack.speed, pack.steering, pack.drive, pack.direction); + if (DEBUG) { + Serial.print("Incoming packet - Speed: "); + Serial.print(pack.speed); + Serial.print(" | Steering: "); + Serial.print(pack.steering); + Serial.print(" | Drive: "); + Serial.print(pack.drive); + Serial.print(" | Direction: "); + Serial.println(pack.direction); + } + } else { + //handleEmergency(); + } +}