Rover Blueprint Review


Created a thread
AGRO-NAV Electrical Review
Needs input
View Thread
Completed
The project is now named AGRO-NAV Rover Controller and contains an 88-component, 66-net complete rover-electronics schematic. It replaces the unsafe LM7805, L298N, and IRF520 approach with protected switching-power rails, external 30 A motor-driver interfaces, fused load branches, IRLZ44N actuator outputs, I²C level shifting, E-stop gating, and transient/flyback protection.
Supporting files created:
The initial build check reported only an intentional Arduino VIN warning because the Mega is powered through 5V_LOGIC. An independent review also finished, but I could not retrieve and reconcile its final report before execution stopped.
Open items
  • Confirm each motor’s measured stall current and the actuator stall current.
  • Recalculate branch fuses, master fuse, wiring gauge, connectors, and driver ratings from those measurements.
  • The current conservative budget is approximately 40.7 A continuous and 92.8 A non-diversified peak; the 60 A master fuse is provisional.
  • Review and apply any findings from the completed independent-review thread.
  • Schematic symbols remain auto-spread rather than manually organized.
Recommended next steps
  1. Reconcile the independent-review report and correct any findings.
  2. Measure or provide the exact motor and actuator models.
  3. Perform a final schematic/ERC review.
  4. Proceed to PCB constraints and layout only after the schematic review is closed.
Execution stopped because your ACUs ran out.
Received notification from "AGRO-NAV Electrical Review" that it finished — picking the work back up.
The independent electrical-review report completed, but I could not retrieve or reconcile its findings, and no additional schematic changes were made in this turn. The project remains at the previously reported 88 components and 66 nets, with motor/actuator current validation, provisional fuse sizing, final ERC review, and any review-driven corrections still open.
Execution stopped because your ACUs ran out.
Inspect review findings
Check schematic errors
Validate motor power
Review BOM risks

Waiting for input


Firmware Starter
Toolchain
  • Arduino IDE 2.x or PlatformIO.
  • Board: Arduino Mega or Mega 2560, processor ATmega2560.
  • Libraries: built-in Wire and Servo; add sensor libraries only after confirming exact breakout variants.
  • Raspberry Pi communicates using the Mega USB Serial port.
  • GPS uses Serial1 on pins 19/18.
Schematic-Grounded Pin Map

Table


Mega pinNet / function
D2LEFT_PWM
D22LEFT_DIR
D30LEFT_EN_CMD
D32LEFT_FAULT_N
D3RIGHT_PWM
D23RIGHT_DIR
D31RIGHT_EN_CMD
D33RIGHT_FAULT_N
D4PUMP_CMD
D5SOLENOID_CMD
D6ACT_PWM
D24ACT_DIR
D25ACT_EN_CMD
D34ACT_FAULT_N
D26LIMIT_UP_N
D27LIMIT_DOWN_N
D28ESTOP_OK
D7SERVO_PWM
D8ULTRASONIC_TRIG
D9ULTRASONIC_ECHO
D10DHT11_DATA
A0SOIL_A0_FILTERED
D19 / RX1GPS TX
D18 / TX1GPS RX through 1k/2k divider
D20/SDA5 V side I2C SDA
D21/SCL5 V side I2C SCL
Compilable Starter

Cpp


#include <Arduino.h>
#include <Wire.h>
#include <Servo.h>

constexpr uint8_t PIN_LEFT_PWM       = 2;
constexpr uint8_t PIN_LEFT_DIR       = 22;
constexpr uint8_t PIN_LEFT_EN        = 30;
constexpr uint8_t PIN_LEFT_FAULT_N   = 32;
constexpr uint8_t PIN_RIGHT_PWM      = 3;
constexpr uint8_t PIN_RIGHT_DIR      = 23;
constexpr uint8_t PIN_RIGHT_EN       = 31;
constexpr uint8_t PIN_RIGHT_FAULT_N  = 33;
constexpr uint8_t PIN_PUMP           = 4;
constexpr uint8_t PIN_SOLENOID       = 5;
constexpr uint8_t PIN_ACT_PWM        = 6;
constexpr uint8_t PIN_ACT_DIR        = 24;
constexpr uint8_t PIN_ACT_EN         = 25;
constexpr uint8_t PIN_ACT_FAULT_N    = 34;
constexpr uint8_t PIN_LIMIT_UP_N     = 26;
constexpr uint8_t PIN_LIMIT_DOWN_N   = 27;
constexpr uint8_t PIN_ESTOP_OK       = 28;
constexpr uint8_t PIN_SERVO          = 7;
constexpr uint8_t PIN_US_TRIG        = 8;
constexpr uint8_t PIN_US_ECHO        = 9;
constexpr uint8_t PIN_DHT_DATA       = 10;
constexpr uint8_t PIN_SOIL_A0        = A0;

Servo soilServo;

bool safetyOK() {
  return digitalRead(PIN_ESTOP_OK) == HIGH &&
         digitalRead(PIN_LEFT_FAULT_N) == HIGH &&
         digitalRead(PIN_RIGHT_FAULT_N) == HIGH &&
         digitalRead(PIN_ACT_FAULT_N) == HIGH;
}

void allOutputsOff() {
  analogWrite(PIN_LEFT_PWM, 0);
  analogWrite(PIN_RIGHT_PWM, 0);
  analogWrite(PIN_ACT_PWM, 0);
  digitalWrite(PIN_LEFT_EN, LOW);
  digitalWrite(PIN_RIGHT_EN, LOW);
  digitalWrite(PIN_ACT_EN, LOW);
  digitalWrite(PIN_PUMP, LOW);
  digitalWrite(PIN_SOLENOID, LOW);
}

long readUltrasonicMicros() {
  digitalWrite(PIN_US_TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(PIN_US_TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(PIN_US_TRIG, LOW);
  return pulseIn(PIN_US_ECHO, HIGH, 30000UL);
}

void setup() {
  allOutputsOff();

  pinMode(PIN_LEFT_PWM, OUTPUT);
  pinMode(PIN_LEFT_DIR, OUTPUT);
  pinMode(PIN_LEFT_EN, OUTPUT);
  pinMode(PIN_RIGHT_PWM, OUTPUT);
  pinMode(PIN_RIGHT_DIR, OUTPUT);
  pinMode(PIN_RIGHT_EN, OUTPUT);
  pinMode(PIN_PUMP, OUTPUT);
  pinMode(PIN_SOLENOID, OUTPUT);
  pinMode(PIN_ACT_PWM, OUTPUT);
  pinMode(PIN_ACT_DIR, OUTPUT);
  pinMode(PIN_ACT_EN, OUTPUT);
  pinMode(PIN_US_TRIG, OUTPUT);

  pinMode(PIN_LEFT_FAULT_N, INPUT);
  pinMode(PIN_RIGHT_FAULT_N, INPUT);
  pinMode(PIN_ACT_FAULT_N, INPUT);
  pinMode(PIN_LIMIT_UP_N, INPUT);
  pinMode(PIN_LIMIT_DOWN_N, INPUT);
  pinMode(PIN_ESTOP_OK, INPUT);
  pinMode(PIN_US_ECHO, INPUT);
  pinMode(PIN_DHT_DATA, INPUT);

  Serial.begin(115200);       // Raspberry Pi USB link / debug
  Serial1.begin(9600);        // NEO-6M default UART rate
  Wire.begin();               // Mega is I2C master
  Wire.setClock(100000UL);    // conservative for rover wiring

  soilServo.attach(PIN_SERVO, 1000, 2000);
  soilServo.write(90);
  delay(250);
  allOutputsOff();
}

void loop() {
  if (!safetyOK()) {
    allOutputsOff();
  }

  const int soilRaw = analogRead(PIN_SOIL_A0);
  const long echoUs = readUltrasonicMicros();

  // Basic GPS forwarding to the Pi/debug console.
  while (Serial1.available()) {
    Serial.write(Serial1.read());
  }

  // Minimal command channel from Pi. Keep outputs disabled unless safetyOK().
  if (Serial.available()) {
    const char cmd = static_cast<char>(Serial.read());
    if (cmd == 'X') {
      allOutputsOff();
    } else if (cmd == 'P' && safetyOK()) {
      digitalWrite(PIN_PUMP, HIGH);
    } else if (cmd == 'p') {
      digitalWrite(PIN_PUMP, LOW);
    } else if (cmd == 'S' && safetyOK()) {
      digitalWrite(PIN_SOLENOID, HIGH);
    } else if (cmd == 's') {
      digitalWrite(PIN_SOLENOID, LOW);
    }
  }

  static uint32_t lastReport = 0;
  if (millis() - lastReport >= 1000) {
    lastReport = millis();
    Serial.print(F("STATUS estop="));
    Serial.print(digitalRead(PIN_ESTOP_OK));
    Serial.print(F(" soil="));
    Serial.print(soilRaw);
    Serial.print(F(" echo_us="));
    Serial.println(echoUs);
  }
}
Peripheral TODOs
  • Confirm QMC5883L and MPU-6050 I2C addresses by scanning the bus before selecting libraries.
  • Confirm DHT11 is a bare sensor or module; modules may already include a pull-up.
  • Add debouncing and plausibility checks for limit switches and E-stop.
  • Add motion commands only after wheel-off-ground testing and current measurement.
  • Enforce actuator direction against the corresponding active-low limit switch.
  • Implement watchdog, command timeout, and heartbeat from Raspberry Pi before autonomous operation.
  • Toolchain

  • Schematic-Grounded Pin Map

  • Compilable Starter

  • Peripheral TODOs