project:
https://github.com/Fabiolus2020/MaccanumRobotWireless
video demo:
controller sketch
//Fabiolus 2021/07/23 #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> RF24 myRadio(8, 9); // CE, CSN //address through which two modules communicate. const byte address[6] = "00001"; //data being sent to the receiver, joystick position, pot values and button count. struct package { int joyposX; int joyposY; int potValue; int stateNum; int SideWayRightState; int SideWayLeftState; int ForwardRightState; int ForwardLeftState; int BackwardRightState; int BackwardLeftState; }; //define object for wieless communication typedef struct package Package; Package data; // Define Joystick Connections #define joyY A0 #define joyX A1 // Define Joystick Values - Start at 512 (middle position) this might change depending on batteries and motor type. int joyposX = 512; int joyposY = 512; //int modeCount; //defining joystick button followed by declaring variables and build mechanical state machine to keep count of joystick and have 3 modes const int buttonPin = 7; int buttonState = 0; // current state of the button int lastButtonState = 0; // previous state of the button int modeState = 0; // remember current led state int stateNum; //LED pin only two modes for this robot #define ledModeStatusCount A3 // Set initial motor speed at 0 int motorspeedModeOne = 0; int motorspeedModeTwo = 0; // Set button for diagonal mode drive, upon pushing button specific direction is iniated. #define buttonSideWayRight 0 #define buttonSideWayLeft 6 #define buttonForwardRight 2 #define buttonForwardLeft 3 #define buttonBackwardRight 4 #define buttonBackwardLeft 5 int SideWayRightState; int SideWayLeftState; int ForwardRightState; int ForwardLeftState; int BackwardRightState; int BackwardLeftState; //Define potentiometer #define Pot A2 int potValue = 0; void setup() { Serial.begin(9600); // set up Serial library at 9600 bps //define Radio as object myRadio.begin(); //set the address myRadio.openWritingPipe(address); myRadio.setPALevel(RF24_PA_MAX); myRadio.setDataRate( RF24_250KBPS ); myRadio.setChannel(115); //Set module as transmitter myRadio.stopListening(); pinMode(ledModeStatusCount, OUTPUT); digitalWrite(ledModeStatusCount, LOW); //joystick select/push button pinMode(buttonPin, INPUT_PULLUP); // initialize the button pin as a input pinMode(buttonSideWayRight, INPUT_PULLUP); pinMode(buttonSideWayLeft, INPUT_PULLUP); pinMode(buttonForwardRight, INPUT_PULLUP); pinMode(buttonForwardLeft, INPUT_PULLUP); pinMode(buttonBackwardRight, INPUT_PULLUP); pinMode(buttonBackwardLeft, INPUT_PULLUP); delay(10); } void loop() { //prepare to capture data to pass wirelessly using data for identifier. myRadio.write(&data, sizeof(data)); // read the pushbutton input pin buttonState = digitalRead(buttonPin); // check if the button is pressed or released // by comparing the buttonState to its previous state, this is the best I could get to being bulletproof and no debouning effect using joystick if (buttonState != lastButtonState) { // change the state of the led when someone pressed the button if (buttonState == 0) { data.stateNum++; if (data.stateNum > 2) data.stateNum = 0; } // remember the current state of the button lastButtonState = buttonState; } data.joyposX = analogRead(joyX); data.joyposY = analogRead(joyY); data.potValue = analogRead(Pot); // Serial.print(data.joyposX); // Serial.println("joyposX"); // Serial.println(data.joyposY); // Serial.println("joyposY"); // Serial.println(data.potValue); //Serial.println(data.stateNum); if (digitalRead(buttonSideWayRight) == LOW) { data.SideWayRightState = 0; } else { data.SideWayRightState = 1; } if (digitalRead(buttonSideWayLeft) == LOW) { data.SideWayLeftState = 0; } else { data.SideWayLeftState = 1; } if (digitalRead(buttonForwardRight) == LOW) { data.ForwardRightState = 0; } else { data.ForwardRightState = 1; } if (digitalRead(buttonForwardLeft) == LOW) { data.ForwardLeftState = 0; } else { data.ForwardLeftState = 1; } if (digitalRead(buttonBackwardRight) == LOW) { data.BackwardRightState = 0; } else { data.BackwardRightState = 1; } if (digitalRead(buttonBackwardLeft) == LOW) { data.BackwardLeftState = 0; } else { data.BackwardLeftState = 1; } Serial.println(data.SideWayRightState); Serial.println(data.SideWayLeftState); Serial.println(data.ForwardRightState); Serial.println(data.ForwardLeftState); Serial.println(data.BackwardRightState); Serial.println(data.BackwardLeftState); }
receiver sketch:
#include <Wire.h> #include <Adafruit_MotorShield.h> // Create the motor shield object with the default I2C address Adafruit_MotorShield AFMS = Adafruit_MotorShield(); // Or, create it with a different I2C address (say for stacking) // Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61); // Select which 'port' M1, M2, M3 or M4. In this case, M1 Adafruit_DCMotor *myMotor1 = AFMS.getMotor(1); Adafruit_DCMotor *myMotor2 = AFMS.getMotor(2); Adafruit_DCMotor *myMotor3 = AFMS.getMotor(3); Adafruit_DCMotor *myMotor4 = AFMS.getMotor(4); #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> RF24 myRadio(8, 9); // CE, CSN //address through which two modules communicate. const byte address[6] = "00001"; struct package { int joyposX; int joyposY; int potValue; int stateNum; int SideWayRightState; int SideWayLeftState; int ForwardRightState; int ForwardLeftState; int BackwardRightState; int BackwardLeftState; }; typedef struct package Package; Package data; // Set initial motor speed at 0 int motorspeedModeOne = 0; int motorspeedModeTwo = 0; void setup() { Serial.begin(9600); AFMS.begin(4000); // OR with a different frequency, say 4KHz while (!Serial); myRadio.begin(); //set the address myRadio.openReadingPipe(0, address); myRadio.setChannel(115); myRadio.setPALevel(RF24_PA_MAX); myRadio.setDataRate( RF24_250KBPS ); //Set module as receiver myRadio.startListening(); } void loop() { if ( myRadio.available()) { myRadio.read( &data, sizeof(data) ); if (data.joyposX < 485)//Going Forward { if (data.stateNum == 1) { myMotor1->run(FORWARD); myMotor2->run(FORWARD); myMotor3->run(FORWARD); myMotor4->run(FORWARD); motorspeedModeOne = map(data.joyposX, 485, 0, 0, 255); myMotor1->setSpeed(motorspeedModeOne); myMotor2->setSpeed(motorspeedModeOne); myMotor3->setSpeed(motorspeedModeOne); myMotor4->setSpeed(motorspeedModeOne); } else if (data.stateNum == 2) { myMotor1->run(FORWARD); myMotor2->run(FORWARD); myMotor3->run(FORWARD); myMotor4->run(FORWARD); motorspeedModeTwo = map(data.potValue, 0, 1023, 0, 255); myMotor1->setSpeed(motorspeedModeTwo); myMotor2->setSpeed(motorspeedModeTwo); myMotor3->setSpeed(motorspeedModeTwo); myMotor4->setSpeed(motorspeedModeTwo); } } if (data.joyposX > 600)//Going Backward { if (data.stateNum == 1) { myMotor1->run(BACKWARD); myMotor2->run(BACKWARD); myMotor3->run(BACKWARD); myMotor4->run(BACKWARD); motorspeedModeOne = map(data.joyposX, 600, 1023, 0, 255); myMotor1->setSpeed(motorspeedModeOne); myMotor2->setSpeed(motorspeedModeOne); myMotor3->setSpeed(motorspeedModeOne); myMotor4->setSpeed(motorspeedModeOne); } else if (data.stateNum == 2)//Going Backward { myMotor1->run(BACKWARD); myMotor2->run(BACKWARD); myMotor3->run(BACKWARD); myMotor4->run(BACKWARD); motorspeedModeTwo = map(data.potValue, 0, 1023, 0, 255); myMotor1->setSpeed(motorspeedModeTwo); myMotor2->setSpeed(motorspeedModeTwo); myMotor3->setSpeed(motorspeedModeTwo); myMotor4->setSpeed(motorspeedModeTwo); } } if (data.joyposY > 600)//Going left { if (data.stateNum == 1) { myMotor1->run(FORWARD); myMotor2->run(BACKWARD); myMotor3->run(FORWARD); myMotor4->run(BACKWARD); motorspeedModeOne = map(data.joyposY, 600, 1023, 0, 255); myMotor1->setSpeed(motorspeedModeOne); myMotor2->setSpeed(motorspeedModeOne); myMotor3->setSpeed(motorspeedModeOne); myMotor4->setSpeed(motorspeedModeOne); } else if (data.stateNum == 2)//Going left { myMotor1->run(FORWARD); myMotor2->run(BACKWARD); myMotor3->run(FORWARD); myMotor4->run(BACKWARD); motorspeedModeTwo = map(data.potValue, 0, 1023, 0, 255); myMotor1->setSpeed(motorspeedModeTwo); myMotor2->setSpeed(motorspeedModeTwo); myMotor3->setSpeed(motorspeedModeTwo); myMotor4->setSpeed(motorspeedModeTwo); } } if (data.joyposY < 470)//Going right { if (data.stateNum == 1) { myMotor1->run(BACKWARD); myMotor2->run(FORWARD); myMotor3->run(BACKWARD); myMotor4->run(FORWARD); motorspeedModeOne = map(data.joyposY, 470, 0, 0, 255); myMotor1->setSpeed(motorspeedModeOne); myMotor2->setSpeed(motorspeedModeOne); myMotor3->setSpeed(motorspeedModeOne); myMotor4->setSpeed(motorspeedModeOne); } else if (data.stateNum == 2)//Going right { myMotor1->run(BACKWARD); myMotor2->run(FORWARD); myMotor3->run(BACKWARD); myMotor4->run(FORWARD); motorspeedModeTwo = map(data.potValue, 0, 1023, 0, 255); myMotor1->setSpeed(motorspeedModeTwo); myMotor2->setSpeed(motorspeedModeTwo); myMotor3->setSpeed(motorspeedModeTwo); myMotor4->setSpeed(motorspeedModeTwo); } } if (data.SideWayRightState == 0) {//GREEN BUTTON if (data.stateNum == 1) { myMotor1->run(FORWARD); myMotor2->run(FORWARD); myMotor3->run(BACKWARD); myMotor4->run(BACKWARD); myMotor1->setSpeed(255); myMotor2->setSpeed(255); myMotor3->setSpeed(255); myMotor4->setSpeed(255); } else if (data.stateNum == 2) { motorspeedModeTwo = map(data.potValue, 0, 1023, 0, 255); myMotor1->run(FORWARD); myMotor2->run(FORWARD); myMotor3->run(BACKWARD); myMotor4->run(BACKWARD); myMotor1->setSpeed(motorspeedModeTwo); myMotor2->setSpeed(motorspeedModeTwo); myMotor3->setSpeed(motorspeedModeTwo); myMotor4->setSpeed(motorspeedModeTwo); } } if (data.SideWayLeftState == 0) {//GREEN BUTTON if (data.stateNum == 1) { myMotor1->run(BACKWARD); myMotor2->run(BACKWARD); myMotor3->run(FORWARD); myMotor4->run(FORWARD); myMotor1->setSpeed(255); myMotor2->setSpeed(255); myMotor3->setSpeed(255); myMotor4->setSpeed(255); } else if (data.stateNum == 2) { motorspeedModeTwo = map(data.potValue, 0, 1023, 0, 255); myMotor1->run(BACKWARD); myMotor2->run(BACKWARD); myMotor3->run(FORWARD); myMotor4->run(FORWARD); myMotor1->setSpeed(motorspeedModeTwo); myMotor2->setSpeed(motorspeedModeTwo); myMotor3->setSpeed(motorspeedModeTwo); myMotor4->setSpeed(motorspeedModeTwo); } } if (data.ForwardRightState == 0) {//YELLOW BUTTON if (data.stateNum == 1) { myMotor1->run(RELEASE); myMotor2->run(RELEASE); myMotor3->run(FORWARD); myMotor4->run(FORWARD); myMotor3->setSpeed(255); myMotor4->setSpeed(255); } else if (data.stateNum == 2) { motorspeedModeTwo = map(data.potValue, 0, 1023, 0, 255); myMotor1->run(RELEASE); myMotor2->run(RELEASE); myMotor3->run(FORWARD); myMotor4->run(FORWARD); myMotor3->setSpeed(motorspeedModeTwo); myMotor4->setSpeed(motorspeedModeTwo); } } if (data.ForwardLeftState == 0) {//YELLOW BUTTON if (data.stateNum == 1) { myMotor1->run(FORWARD); myMotor2->run(FORWARD); myMotor3->run(RELEASE); myMotor4->run(RELEASE); myMotor1->setSpeed(255); myMotor2->setSpeed(255); } else if (data.stateNum == 2) { motorspeedModeTwo = map(data.potValue, 0, 1023, 0, 255); myMotor1->run(FORWARD); myMotor2->run(FORWARD); myMotor3->run(RELEASE); myMotor4->run(RELEASE); myMotor1->setSpeed(motorspeedModeTwo); myMotor2->setSpeed(motorspeedModeTwo); } } else if (data.BackwardRightState == 0) {// BLUE BUTTON if (data.stateNum == 1) { myMotor1->run(BACKWARD); myMotor2->run(BACKWARD); myMotor3->run(RELEASE); myMotor4->run(RELEASE); myMotor2->setSpeed(255); myMotor3->setSpeed(255); } else if (data.stateNum == 2) { motorspeedModeTwo = map(data.potValue, 0, 1023, 0, 255); myMotor1->run(BACKWARD); myMotor2->run(BACKWARD); myMotor3->run(RELEASE); myMotor4->run(RELEASE); myMotor1->setSpeed(motorspeedModeTwo); myMotor2->setSpeed(motorspeedModeTwo); } } else if (data.BackwardLeftState == 0) {// BLUE BUTTON if (data.stateNum == 1) { myMotor1->run(RELEASE); myMotor2->run(RELEASE); myMotor3->run(BACKWARD); myMotor4->run(BACKWARD); myMotor3->setSpeed(255); myMotor4->setSpeed(255); } else if (data.stateNum == 2) { motorspeedModeTwo = map(data.potValue, 0, 1023, 0, 255); myMotor1->run(RELEASE); myMotor2->run(RELEASE); myMotor3->run(BACKWARD); myMotor4->run(BACKWARD); myMotor3->setSpeed(motorspeedModeTwo); myMotor4->setSpeed(motorspeedModeTwo); } } myMotor1->run(RELEASE); myMotor2->run(RELEASE); myMotor3->run(RELEASE); myMotor4->run(RELEASE); } }
controller schema
https://github.com/Fabiolus2020/MaccanumRobotWireless/blob/main/controller_bb.png
receiver schema:
https://github.com/Fabiolus2020/MaccanumRobotWireless/blob/main/receiver_bb.png