Arduino Code Crashes At Random Points During Controlling a Tank Vehicle

So I'm doing a project right now of controlling a Tank Vehicle that has 4 9V DC Motors that are controlled by a Adafruit MotorShield V2.3 on top of a Arduino Uno WiFi Rev2.

And I control it with an Xbox Wireless Controller, that is connected through Bluetooth to a Raspberry Pi, which then sends the controller-signals as UDP packets through WiFi to the Arduino. (Don't ask why so complicated, its required by how the project is supposed to go further, but the Raspberry Pi kinda has to be involved)

And generelly it's working fine, I have a simple Arduino code that interprets the UDP packets and controls the motors just fine, but every now and then the Arduino program seems to just stop working (based on the stopped/interrupted Serial monitor output) and if the motor is unfortunately still turned on it just drives without stopping and could run into walls, which of course it shouldn't. Now I wanna know if maybe something in my code is prone to crash randomly, if it has something to do with the UDP packets, or my friend proposed it could have something to do with the quartz crystal clock in the Arduino (the Arduino is probably around or more than 4 years old), which then might be a hardware problem, so I just wanna know if theres anything I can do in the software part, before switchting out any parts.

(And I've already re-created the error with Delays behind the Serial Output and without any Serial Monitor Output in the code at all)

Thanks

Code:

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFiUdp.h>

char ssid[] = "Tank-WiFi";
char pass[] = "xxxxxxx";

int status = WL_IDLE_STATUS;
unsigned int localPort = 2390;
IPAddress ip(xxx, xxx, x, xxx);

char packet[255];
char ReplyBuffer[] = "acknowledged";

int Speed = 110;

Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *RH = AFMS.getMotor(1);
Adafruit_DCMotor *LH = AFMS.getMotor(2);
Adafruit_DCMotor *LV = AFMS.getMotor(3);
Adafruit_DCMotor *RV = AFMS.getMotor(4);
WiFiUDP Udp;


void setup() {
  Serial.begin(250000);
  while (!Serial) {;}

  AFMS.begin();
  RH->setSpeed(Speed);
  RV->setSpeed(Speed);
  LH->setSpeed(Speed);
  LV->setSpeed(Speed);
  
  checkWiFi();
  WiFi.config(ip);   //Wichtig
  connectToWiFi();
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();
  Serial.println("\nStarting connection to server...");
  Udp.begin(localPort);
}

void loop() {
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Udp.read(packet, UDP_TX_PACKET_MAX_SIZE);
    int UDP = atoi(packet);
    
    switch (UDP) {
      case 0:
        Serial.println("STOP");
        RH->run(RELEASE); RV->run(RELEASE);
        LH->run(RELEASE); LV->run(RELEASE);
        break;
      case 1:
        Serial.println("FORWARD");
        RH->run(FORWARD); RV->run(FORWARD);
        LH->run(FORWARD); LV->run(FORWARD);
        break;
      case 2:
        Serial.println("BACKWARD");
        RH->run(BACKWARD);RV->run(BACKWARD);
        LH->run(BACKWARD);LV->run(BACKWARD);
        break;
      case 3:
        Serial.println("RIGHT");
        RH->run(BACKWARD);RV->run(BACKWARD);
        LH->run(FORWARD); LV->run(FORWARD);
        break;
      case 4:
        Serial.println("LEFT");
        RH->run(FORWARD); RV->run(FORWARD);
        LH->run(BACKWARD);LV->run(BACKWARD);
        break;
        
      case 5:
        Serial.println("SPEED CHANGE TO 80");
        Speed = 80;
        RH->setSpeed(80); RV->setSpeed(80);
        LH->setSpeed(80); LV->setSpeed(80);
        break;
      case 6:
        Serial.println("SPEED CHANGE TO 90");
        Speed = 90;
        RH->setSpeed(90); RV->setSpeed(90);
        LH->setSpeed(90); LV->setSpeed(90);
        break;
      case 7:
        Serial.println("SPEED CHANGE TO 100");
        Speed = 100;
        RH->setSpeed(100); RV->setSpeed(100);
        LH->setSpeed(100); LV->setSpeed(100);
        break;
      case 8:
        Serial.println("SPEED CHANGE TO 110");
        Speed = 110;
        RH->setSpeed(110); RV->setSpeed(110);
        LH->setSpeed(110); LV->setSpeed(110);
        break;
    }
  }
}



//Unimportant

void checkWiFi() {
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    while (true);
  }
  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
    }
}

void connectToWiFi() {
  Serial.print("Attempting to connect to WPA SSID: ");
  Serial.println(ssid);
  while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    delay(5000);
    Serial.println("Trying again...");
  }
}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}

void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 5; i >= 0; i--) {
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
    if (i > 0) {
      Serial.print(":");
    }
  }
  Serial.println();
}

does the program crash or the UDP datagrams stop being received?

The first thing that pops into my mind from the description of the issue is RAM.

Serial.prints consume a lot of clock cycles. I use them with the initial development as I write one function or another but I remove them as soon as possible. I typically comment them out and use them later on for any troubleshooting. And all the "String thingies in between double quotes" take up ram.

The 2nd thing that pops into my mind is power.

well i dont get any crash notification in the Arduino IDE or anything but i believe its not just stopping the ability to receive packets, because when it happened it one time stopped the serial output in the middle of the word. it didnt just stop writing because it didnt receive anything anymore, it looked more like something actively stopped the process in the middle of serial output.

like the last line in the Serial monitor was:
"RIG" even though it should have said "RIGHT" if it worked normally and just stopped with the packets

Okay well, I tried it once without any Serial Monitor and also with the Commands commented out and it happened again, and the RAM is not close to being full at all. The UNO WiFi Rev2.3 is a megaAVRBoard so it has plenty of RAM.

and the Power problem could technically be a problem, but i dont think so, if the motors run fine for 10 min without any problem and then suddenly the program stopped reacting and the motors even keep working the power like doesnt seem to be the problem right?

perhaps rather than connectionless UDP try a TCP connection - it should inform you if there are problems such as lost connection
as @Idahowalker mentioned suspect power supply problems, e.g.noise
run the microcontroller off an independent power supply?

thanks for the suggestions first of all.
i mean yes i could switch to TCP connection but i wanna see if it could be something else first, because that would require a lot to be changed.
and with the power supply problem: i mean i had the motorshield connected to an extra power supply and the arduino connected to a USB Output from a PC to read the Serial Output. Doesnt that count as independent power supplies? like the USB Output supplies the Arduino with enough Power to run the 5V on it, doesnt it?

the PC counts as an independent power supply so long as your control system does not overload it - how do you control the motors?
could the arduino be picking up electro magnetic interfearence from the motor control?
I had a prototype control system based on an arduino which controlled a couple of motors, a pump and a solenoid - when switching particular combinations the Arduino would reset. I found using shielded cables between the Arduino and motors etc fixed the problem.


theres an Adafruit Motor Shield V2 stacked right on top of the Arduino. I haven't heard or read anywhere about that motor shield causing electromagnetic problems, but maybe you're right, because it seems pretty random but maybe its a certain combination of turning with the motors. can you send me a link of how those shielded cables would look like, or how i could shield the existing cables?
Thank you

photo shows the grey cable which is screened with 5 cores - example Ebay screened cables
the green wire is connected to the cable screen and the metal case of the unit to provide the earth screen - the other wires goto the connections for the motors etc (motors are small so no problems of cable overload)

That statement should be checked, as it sounds exactly like what's happening, all the motors pull stall current simultaneously, voltage drops out. Small motors like that can easily pull many amps (or even tens of amps in some cases) at stall/startup.

The wires taking power to the motor controller are suspiciously skinny. What is the power source for this motor controller? Can the controller handle the stall-current of the motors at all?

@MarkT I was referring to the wires in my test rig which were similar to those connected to the original PLC
I agree the wires in the post #9 photo look very thin

so the cables should be fine. they got send with the Power bank and its a Standard DC Cable that should be capaple of transferring the power. the Power-Bank has a 12V and maximum 5A Output. The Motor Shield is rated for 1.2A per Channel, but you might be right, because it also says, 3A peak for 20ms, whatever that means. Im gonna hook up an Amp-Meter and see how much Power the Motors draw. I didnt do that before, because i read that it was rated for 4 DC Motors and i didnt begin this project, my predecessor bought all the components and i just assumed they paid attention to that.
Thanks

so the multimeter never showed anything even above 1.8A at a time. So i dont think the motors are pulling too much Power i mean the Multimeter might be lacking behind and at peak moments when i change the direction of driving, but i dont think it should go above the 1.2A per channel

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.