MARS ROVER USING NODEMCU(3D PRINTED)

Circuit Diagram

A Mars rover is a remote-controlled robot designed to travel on the surface of Mars. we have see several mars rovers like Spirit , Opportunity , Curiosity and Perseverance. these rovers are highly designed to operate on uneven terrains. I got amazed with the 6 wheel design of such rovers. so in this tutorial I am showing how to build a fully functional model MARS rover.

3D Printing

download from here

Receiver code

//RX TEST
#include <ESP8266WiFi.h>
#include <espnow.h>
#include <FastLED.h>
#define NUM_LEDS 2
#define DATA_PIN 0
CRGB leds[NUM_LEDS];
const int motor1a = 2;
const int motor1b = 14;
const int motor2a = 13;
const int motor2b = 12;

uint8_t broadcastAddress[] = {0xAC, 0x0B, 0xFB, 0xCE, 0x8B, 0x16};//MASTER ESP8266 Board MAC Address:  AC:0B:FB:CF:16:91
String success;


typedef struct struct_message {
  int button;
} struct_message;

int IN_button_state;
int OUT_button_state;


// Create a struct_message called DHTReadings to hold sensor readings
struct_message outgoingmsg;

// Create a struct_message to hold incoming sensor readings
struct_message incomingmsg;

// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  Serial.print("Last Packet Send Status: ");
  if (sendStatus == 0){
    Serial.println("Delivery success");
  }
  else{
    Serial.println("Delivery fail");
  }
}

// Callback when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
  memcpy(&incomingmsg, incomingData, sizeof(outgoingmsg));
  Serial.print("Bytes received: ");
  Serial.println(len);
//store incoming data in variable
  IN_button_state = incomingmsg.button;
  if (IN_button_state==1){forward();}
  if (IN_button_state==2){backward();}
  if (IN_button_state==3){turnleft();}
  if (IN_button_state==4){turnright();}
  if (IN_button_state==5){nomotion();}
  
  
}

void getReadings(){
  // Read 
 OUT_button_state = analogRead(A0);

 delay(100);
//OUT 
  Serial.println("OUTGOING MESSAGES");
  
  Serial.println(OUT_button_state);
 }

void printIncomingMessage(){
  // Display Readings in Serial Monitor
  //IN
  Serial.println("INCOMING MESSAGES");
  
  Serial.println(IN_button_state);

  
}
 
void setup() {
 FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); 
  pinMode(motor1a,OUTPUT);
    pinMode(motor1b,OUTPUT);
      pinMode(motor2a,OUTPUT);
        pinMode(motor2b,OUTPUT);
        pinMode(A0,INPUT);
  
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Set ESP-NOW Role
  esp_now_set_self_role(ESP_NOW_ROLE_COMBO);

  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);
  
  // Register peer
  esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0);
  
  // Register for a callback function that will be called when data is received
  esp_now_register_recv_cb(OnDataRecv);
}
 
void loop() {
 
    getReadings();
    

    //Set values to send
    outgoingmsg.button = OUT_button_state;
   

    // Send message via ESP-NOW
    esp_now_send(broadcastAddress, (uint8_t *) &outgoingmsg, sizeof(outgoingmsg));

    printIncomingMessage();
  }
  void forward()
{digitalWrite(motor1a,1);
 digitalWrite(motor2a,1);
 digitalWrite(motor1b,0);
 digitalWrite(motor2b,0);
 leds[0] = CRGB::Green;
 leds[1] = CRGB::Green;
  FastLED.show();
  delay(50);
  }
 void backward()
{digitalWrite(motor1a,0);
 digitalWrite(motor2a,0);
 digitalWrite(motor1b,1);
 digitalWrite(motor2b,1);
 leds[0] = CRGB::Red;
 leds[1] = CRGB::Red;
  FastLED.show();
  delay(50);
  }
 void turnleft()
{digitalWrite(motor1a,1);
 digitalWrite(motor2a,0);
 digitalWrite(motor1b,0);
 digitalWrite(motor2b,1);
 leds[0] = CRGB::Green;
  FastLED.show();
  delay(50);
  }
 void turnright()
{
  digitalWrite(motor1a,0);
 digitalWrite(motor2a,1);
 digitalWrite(motor1b,1);
 digitalWrite(motor2b,0);
 leds[1] = CRGB::Green;
  FastLED.show();
  delay(50);}
 void nomotion()
{digitalWrite(motor1a,0);
 digitalWrite(motor2a,0);
 digitalWrite(motor1b,0);
 digitalWrite(motor2b,0);}

Transmitter Program


#include <ESP8266WiFi.h>
#include <espnow.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
uint8_t broadcastAddress[] = {0xAC, 0x0B, 0xFB, 0xCF, 0x16, 0x91};//SLAVE ESP8266 Board MAC Address: AC:0B:FB:CE:8B:16


String success;
#define upButton 2
#define downButton 14
#define leftButton 13
#define rightButton 12

typedef struct struct_message 
{
int button;
} 
struct_message;
int IN_button_state;
int OUT_button_state;
struct_message outgoingmsg;
struct_message incomingmsg;

// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  Serial.print("Last Packet Send Status: ");
  if (sendStatus == 0){
    Serial.println("Delivery success");
  }
  else{
    Serial.println("Delivery fail");
  }
}

// Callback when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
  memcpy(&incomingmsg, incomingData, sizeof(outgoingmsg));
  Serial.print("Bytes received: ");
  Serial.println(len);
//store incoming data in variable
  IN_button_state = incomingmsg.button;
  
 
}

void getReadings(){

 if((digitalRead(upButton)==0)&&(digitalRead(downButton)==1)&&(digitalRead(leftButton)==1)&&(digitalRead(rightButton)==1))
{
 OUT_button_state = 1;
 }
 if((digitalRead(upButton)==1)&&(digitalRead(downButton)==0)&&(digitalRead(leftButton)==1)&&(digitalRead(rightButton)==1))
{
 OUT_button_state = 2;
 }
 if((digitalRead(upButton)==1)&&(digitalRead(downButton)==1)&&(digitalRead(leftButton)==0)&&(digitalRead(rightButton)==1))
{
 OUT_button_state = 3;
 }
  if((digitalRead(upButton)==1)&&(digitalRead(downButton)==1)&&(digitalRead(leftButton)==1)&&(digitalRead(rightButton)==0))
{
 OUT_button_state = 4;
 }
  if((digitalRead(upButton)==1)&&(digitalRead(downButton)==1)&&(digitalRead(leftButton)==1)&&(digitalRead(rightButton)==1))
{
 OUT_button_state = 5;
 }
}
 
void setup() {
  
  Serial.begin(115200);
  pinMode(upButton,INPUT_PULLUP);
  pinMode(downButton,INPUT_PULLUP);
  pinMode(leftButton,INPUT_PULLUP);
  pinMode(rightButton,INPUT_PULLUP);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Set ESP-NOW Role
  esp_now_set_self_role(ESP_NOW_ROLE_COMBO);

  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);
  
  // Register peer
  esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0);
  
  // Register for a callback function that will be called when data is received
  esp_now_register_recv_cb(OnDataRecv);
}
void printIncomingMessage(){
  // Display Readings in Serial Monitor
  //IN
  Serial.println("INCOMING MESSAGES");
  
  Serial.println(IN_button_state);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(10, 20);
  display.println("LIGHT: ");
  display.setCursor(80, 20);
  display.println(IN_button_state);
  display.display(); 
  delay(10);

  
}
 
void loop() {
  

    //Get DHT readings
    getReadings();

    //Set values to send
    outgoingmsg.button = OUT_button_state;
   

    // Send message via ESP-NOW
    esp_now_send(broadcastAddress, (uint8_t *) &outgoingmsg, sizeof(outgoingmsg));
    printIncomingMessage();

}

Leave a comment