Boat Project code help

hello i am building a boat that fishes trash out of the water. now we have 2 codes that i smashed together in one big code but now my propulsion system doesnt work. let me explain the layout.

the boat has 2 waterwheels on each side of the boat. the RPM is controlled by a sonar sensor. so when it gets to close to the side it will correct one side of the waterwheel. that whas one code,

the second code is for a system to sort different color plastic balls,

both systems worked fine with two codes. but when i smashed them together the boats propulsion system doesnt work anymore. i used serial print to see if the sonar sensor gets the right readings and it does. am a bit lost help would be much appreciated.

// motor pins
int motorR1 = 2;
int motorR2 = 3;
int motorL1 = 4;
int motorL2 = 5;
int pmwR = 6;
int pmwL = 9;
// sonar variable
long duration1;  //zijkant
int distance1; 
long duration2; //voorkant
int distance2;
//sonar pins
const int trigPinF = 7; //voorkant
const int echoPinF = 8;

// Define color sensor pins
#include <Servo.h>
Servo ServoR; //rood
Servo ServoG; //groen
Servo ServoB; //blauw
Servo ServoY; //geel

#define S0 10
#define S1 11
#define S2 12
#define S3 13
#define sensorOut A4

// Variables for Color Pulse Width Measurements
int redPW = 0;
int greenPW = 0;
int bluePW = 0;

void setup() {
{ // servo pins
  ServoR.attach(A0); //rood
  ServoG.attach(A1); //groen
  ServoB.attach(A2); //blauw
  ServoY.attach(A3); //geel
	// Set S0 - S3 as outputs
	pinMode(S0, OUTPUT);
	pinMode(S1, OUTPUT);
	pinMode(S2, OUTPUT);
	pinMode(S3, OUTPUT);
}
{	// Set Pulse Width scaling to 20%
	digitalWrite(S0,HIGH);
	digitalWrite(S1,LOW);
}
{ // motor
  pinMode(motorR1, OUTPUT);
  pinMode(motorR2, OUTPUT);
  pinMode(motorL1,  OUTPUT);
  pinMode(motorL2, OUTPUT);
  // pwm motors
  pinMode(6, OUTPUT); //Rechts
  pinMode(9, OUTPUT); //Links
}
{ // sonar sensors F
  pinMode(trigPinF, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPinF, INPUT); // Sets the echoPin as an Input
}
{  // Setup Serial Monitor
	Serial.begin(9600);
}
}

void loop() {
{ // aandrijving en sonar sensor
if (distance2 <30  && distance2 > 40) 
  {
    analogWrite(6, 180);
    analogWrite(9, 180);
  }
if (distance2 < 30)
  {
    analogWrite(6, 255);
    analogWrite(9, 0);
  }
if (distance2 > 40)
  {
    analogWrite(6, 0);
    analogWrite(9, 180);
  }
  // motors
    digitalWrite(motorR1, LOW);
    digitalWrite(motorR2, HIGH);
    digitalWrite(motorL1, LOW);
    digitalWrite(motorL2, HIGH);
}
{
  //sonar sensor F
  digitalWrite(trigPinF, LOW); // sonar sensor berekening naar cm zijkant
  delayMicroseconds(2);
  digitalWrite(trigPinF, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPinF, LOW);
  duration2 = pulseIn(echoPinF, HIGH);
  distance2 = duration2 * 0.034 / 2;
}

{ // kleuren sensor en servo's
	redPW = getRedPW();	// Read Red Pulse Width
	delay(200);
	greenPW = getGreenPW(); 	// Read Green Pulse Width
	delay(200);
	bluePW = getBluePW(); 	// Read Blue Pulse Width
	delay(200);
	// Print output to Serial Monitor
	Serial.print("Red PW = ");
	Serial.print(redPW);
	Serial.print(" - Green PW = ");
	Serial.print(greenPW);
	Serial.print(" - Blue PW = ");
	Serial.println(bluePW);

 //servo move
if (redPW > 120 && greenPW > 120 && bluePW > 120) {
 ServoR.write(0);
 ServoG.write(85);
 ServoB.write(85);
 ServoY.write(0);
} else {
if (redPW < 80 && greenPW > 80 && bluePW > 80) {
 ServoR.write(60);
 delay(10000);
}
if (greenPW < 100 && redPW > 100 && bluePW > 90) {
 ServoG.write(30);
 delay(10000);
}
if (bluePW < 97 && redPW > 100 && greenPW > 90) {
  ServoB.write(30);
  delay(10000);
}
if (redPW < 80 && greenPW < 80 && bluePW <105) {
  ServoY.write(60);
  delay(10000);
}
}
}
}

// Function to read Red Pulse Widths
int getRedPW() {
	digitalWrite(S2,LOW);	// Set sensor to read Red only
	digitalWrite(S3,LOW);
	int PW; 	// Define integer to represent Pulse Width
	PW = pulseIn(sensorOut, LOW); 	// Read the output Pulse Width
	return PW; 	// Return the value
}
// Function to read Green Pulse Widths
int getGreenPW() {
	digitalWrite(S2,HIGH); 	// Set sensor to read Green only
	digitalWrite(S3,HIGH); 
	int PW;	// Define integer to represent Pulse Width
	PW = pulseIn(sensorOut, LOW); 	// Read the output Pulse Width
	return PW; 	// Return the value
}
// Function to read Blue Pulse Widths
int getBluePW() {
	digitalWrite(S2,LOW); 	// Set sensor to read Blue only
	digitalWrite(S3,HIGH);
	int PW; // Define integer to represent Pulse Width
	PW = pulseIn(sensorOut, LOW); 	// Read the output Pulse Width
	return PW; 	// Return the value
}

does it even compile ? I doubt so you have code outside the functions...

yes it verify's,

1 Like

ah sorry I got fooled by your indentation and all those useless {}... (reading on my iPhone)

your code is weird. The loop starts with

    if (distance2 < 30  && distance2 > 40)

first distance2 has never been calculated and how can a distance be both < 30 AND > 40 ???


the loop waits 600ms when reading the pulse, nothing else happens when there is a delay().
also the delay for 10s is not helping...

1 Like

Kindly organize the code. For example, library should be included on top of the code. Not in the middle. After that should come the pin definitions.

  1. I see multiple occurrences of a pin name and number, where you then continue to refer to the pin number explicitly in the code instead of using the name you've given it. This not only adds confusion, it makes it extremely likely you'll misuse either the pin number or the name.
  2. ANYWHERE you explicitly read or write an analog pin or a digital pin, please use a name consistently. That will improve the clarity of the code.
  3. if a pin number is defined using an int, make it a constant. That prevents inadvertent modification, and allows the compiler to treat it appropriately, instead of reserving space because 'it could be a variable'.
  4. replace all delays with appropriately coded millis() functionality.

With all that done, bring your code back so we can help you with it.

What were the outputs of the programs? (looks more like three to me: motor, color sensor, distance sensor)

This problem is probably caused by your re-wiring. Your "boat" should be doing endless "Reverse Skid Left" turns with Left Enable ON, Left Reverse ON and Right Enable OFF, Right Forward ON.

Motor steering simulation: dcMotorSteering - Wokwi ESP32, STM32, Arduino Simulator

hey tnx for the tips. i think made it now in a good order dint know it had such a inpact on the programing code. just watched some yt about it.

this is my code now. there is 1 thing i dont understand how to use the millis() functuion. i just learned the diffrence between delay now. cud you give me some advice about it?. going to try the hole night to understand it. need to finish it for tommorow. the other thing is that i am not sure i need to change the int to a const for the distance2, redPW, greenPW and bluePW

// --> libraries --> defines and constants --> global variables --> defined functions --> setup --> loop
#include <Servo.h>
Servo ServoR; //rood
Servo ServoG; //groen
Servo ServoB; //blauw
Servo ServoY; //geel
// color sensor
#define S0 10
#define S1 11
#define S2 12
#define S3 13
#define sensorOut A4
// motor pins
const int motorR1 = 2;
const int motorR2 = 3;
const int motorL1 = 4;
const int motorL2 = 5;
const int pmwR = 6;
const int pmwL = 9;
//Milliseconde setup
unsigned long currentMillis1 = 0; //servos
const unsigned long delayDuration1 = 10000; // Vertraging van 10 seconden#
unsigned long currentMillis2 = 0; // color reading    
const unsigned long delayDuration2 = 200; // Vertraging van 10 seconden
//sonar pins
const int trigPinF = 7; 
const int echoPinF = 8;
// sonar variable
long duration2; 
int distance2;
// Variables for Color Pulse Width Measurements          
int redPW = 0;
int greenPW = 0;
int bluePW = 0;

// Function to read Red Pulse Widths
int getRedPW() {
	digitalWrite(S2,LOW);	// Set sensor to read Red only
	digitalWrite(S3,LOW);
	int PW; 	// Define integer to represent Pulse Width
	PW = pulseIn(sensorOut, LOW); 	// Read the output Pulse Width
	return PW; 	// Return the value
}
// Function to read Green Pulse Widths
int getGreenPW() {
	digitalWrite(S2,HIGH); 	// Set sensor to read Green only
	digitalWrite(S3,HIGH); 
	int PW;	// Define integer to represent Pulse Width
	PW = pulseIn(sensorOut, LOW); 	// Read the output Pulse Width
	return PW; 	// Return the value
}
// Function to read Blue Pulse Widths
int getBluePW() {
	digitalWrite(S2,LOW); 	// Set sensor to read Blue only
	digitalWrite(S3,HIGH);
	int PW; // Define integer to represent Pulse Width
	PW = pulseIn(sensorOut, LOW); 	// Read the output Pulse Width
	return PW; 	// Return the value
}

void setup() {
 // servo pins
  ServoR.attach(A0); //rood
  ServoG.attach(A1); //groen
  ServoB.attach(A2); //blauw
  ServoY.attach(A3); //geel
	// Set S0 - S3 as outputs
	pinMode(S0, OUTPUT);
	pinMode(S1, OUTPUT);
	pinMode(S2, OUTPUT);
	pinMode(S3, OUTPUT);
  // Set Pulse Width scaling to 20%
	digitalWrite(S0,HIGH);
	digitalWrite(S1,LOW);
   // motor
  pinMode(motorR1, OUTPUT);
  pinMode(motorR2, OUTPUT);
  pinMode(motorL1,  OUTPUT);
  pinMode(motorL2, OUTPUT);
  // pwm motors
  pinMode(pmwR, OUTPUT); //Rechts
  pinMode(pmwL, OUTPUT); //Links
  // sonar sensors F
  pinMode(trigPinF, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPinF, INPUT); // Sets the echoPin as an Input

  Serial.begin(9600);
}

void loop() {
  // bestuuring/aandrijving
  digitalWrite(trigPinF, LOW); // sonar sensor berekening naar cm zijkant
  delayMicroseconds(2);
  digitalWrite(trigPinF, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPinF, LOW);
  duration2 = pulseIn(echoPinF, HIGH);
  distance2 = duration2 * 0.034 / 2;

// kleuren sensor en servo's
	redPW = getRedPW();	// Read Red Pulse Width
	currentMillis2 = millis(); // Reset de tijd
  while (millis() - currentMillis2 < delayDuration1) {
  }
	greenPW = getGreenPW(); 	// Read Green Pulse Width
	currentMillis2 = millis(); // Reset de tijd
  while (millis() - currentMillis2 < delayDuration1) {
  }
	bluePW = getBluePW(); 	// Read Blue Pulse Width
  currentMillis2 = millis(); // Reset de tijd
  while (millis() - currentMillis2 < delayDuration1) {
  }
	// Print output to Serial Monitor
	Serial.print("Red PW = ");
	Serial.print(redPW);
	Serial.print(" - Green PW = ");
	Serial.print(greenPW);
	Serial.print(" - Blue PW = ");
	Serial.println(bluePW);
  
  // motors aandrijving
  digitalWrite(motorR1, LOW);
  digitalWrite(motorR2, HIGH);
  digitalWrite(motorL1, LOW);
  digitalWrite(motorL2, HIGH);

if (distance2 <30  && distance2 > 40)  // this means if the boat is between those variables it will do this action
  {
    analogWrite(pmwR, 180);
    analogWrite(pmwL, 180);
  }
if (distance2 < 30)
  {
    analogWrite(pmwR, 255);
    analogWrite(pmwL, 0);
  }
if (distance2 > 40)
  {
    analogWrite(pmwR, 0);
    analogWrite(pmwL, 180);
  }

   //servo move
if (redPW > 120 && greenPW > 120 && bluePW > 120) //is for the sorting system keeps all servos on clossed pos, other if statemetns to open them.
  {
    ServoR.write(0);
    ServoG.write(85);
    ServoB.write(85);
    ServoY.write(0);
   } else {
if (redPW < 80 && greenPW > 80 && bluePW > 80)   //the delay is for keeping the servos open long enough.
  {
    ServoR.write(60);
    currentMillis1 = millis(); // Reset de tijd
    while (millis() - currentMillis1 < delayDuration1) {
  }}
if (greenPW < 100 && redPW > 100 && bluePW > 90) 
  {
    ServoG.write(30);
    currentMillis1 = millis(); // Reset de tijd
    while (millis() - currentMillis1 < delayDuration1) {
  }}
if (bluePW < 97 && redPW > 100 && greenPW > 90)
  {
    ServoB.write(30);
    currentMillis1 = millis(); // Reset de tijd
    while (millis() - currentMillis1 < delayDuration1) {
  }}
if (redPW < 80 && greenPW < 80 && bluePW <105) {
  ServoY.write(60);
    currentMillis1 = millis(); // Reset de tijd
    while (millis() - currentMillis1 < delayDuration1) {
  }}
 }
}

i edited this code and i came to this.

When delay(...)translates to stay here and do nothing

this

    currentMillis1 = millis(); // Reset de tijd
    while (millis() - currentMillis1 < delayDuration1) {
  }

translates to rotate while you stay here and do nothing.

I think you need to look at non-blocking programming and state machines.
Take a look at Blink without delay and this code:

void setup(){
  Serial.begin(115200);
}

void loop(){
  doTask1();
}

enum class State{
  doSomething,
  doWait
};

State state = State::doSomething;
auto startMillis = millis();
int counter = 0;

auto duration = 1000;

void doTask1(){
  auto now = millis();
  switch(state){
    case State::doSomething:
      counter++;
      Serial.print("doSomething ");
      Serial.println(counter);
      if(counter >= 5){
        counter = 0;
        startWait();
      }
      break;
    case State::doWait:
      if(now - startMillis > duration){
        Serial.println("done waiting");
        state = State::doSomething;
      }
      break;
  }
}

void startWait(){
  Serial.println("Wait...");
  startMillis = millis();
  state = State::doWait;
}

The line

is still in the code.

Don't you understand, that the condition will never matched?
If no, please give an example value of distance2 that less than 30 AND more than 40 SIMULTANEOUSLY?

may be Schrödinger's cat calculated distance2 :wink:

2 Likes

aa i see. i put it in chatgtp by what you mean. i think i understand now. chatgtp gave me this,

if (distance2 >= 30 && distance2 <= 40) 

it tells me this is the correct way say that if the sensor reads between 30 and 40 the if statement becomes true, is this correct?

i know chatgtp is always correct.

chatGPT is right that time :wink:

but you still need to calculate distance2 before using it...

the calculate distance2 in the first row of code line in void loop right? or do i have to say or put it in a different row?

I was looking at the code from the first post

if you moved it at the start of the loop, then that's fine.

you could use if / else to make the code faster

hey tnx for the tips. we just uploaded the code but sadly nothing works now hehe. cud it be becusee every system runs in one loop. would it be better to make the servos and motors in diffrent voids?
am fully lost now. going to hook up a seccond arduino and run the boat on two i think.

can you post your latest code and up to date diagram of your circuit including power supply details?

yes i can, this is the code now. and i just made the diagram. this is all new to me first project for school so i hope its readable. (cud not find a good software to put it all in)

// --> libraries --> defines and constants --> global variables --> defined functions --> setup --> loop
#include <Servo.h>
Servo ServoR; //rood
Servo ServoG; //groen
Servo ServoB; //blauw
Servo ServoY; //geel
// color sensor
#define S0 10
#define S1 11
#define S2 12
#define S3 13
#define sensorOut A4
// motor pins
const int motorR1 = 2;
const int motorR2 = 3;
const int motorL1 = 4;
const int motorL2 = 5;
const int pmwR = 6;
const int pmwL = 9;
//Milliseconde setup
unsigned long currentMillis1 = 0; //servos
const unsigned long delayDuration1 = 10000; // Vertraging van 10 seconden#
unsigned long currentMillis2 = 0; // color reading    
const unsigned long delayDuration2 = 200; // Vertraging van 10 seconden
//sonar pins
const int trigPinF = 7; 
const int echoPinF = 8;
// sonar variable
long duration2; 
int distance2;
// Variables for Color Pulse Width Measurements          
int redPW = 0;
int greenPW = 0;
int bluePW = 0;

// Function to read Red Pulse Widths
int getRedPW() {
	digitalWrite(S2,LOW);	// Set sensor to read Red only
	digitalWrite(S3,LOW);
	int PW; 	// Define integer to represent Pulse Width
	PW = pulseIn(sensorOut, LOW); 	// Read the output Pulse Width
	return PW; 	// Return the value
}
// Function to read Green Pulse Widths
int getGreenPW() {
	digitalWrite(S2,HIGH); 	// Set sensor to read Green only
	digitalWrite(S3,HIGH); 
	int PW;	// Define integer to represent Pulse Width
	PW = pulseIn(sensorOut, LOW); 	// Read the output Pulse Width
	return PW; 	// Return the value
}
// Function to read Blue Pulse Widths
int getBluePW() {
	digitalWrite(S2,LOW); 	// Set sensor to read Blue only
	digitalWrite(S3,HIGH);
	int PW; // Define integer to represent Pulse Width
	PW = pulseIn(sensorOut, LOW); 	// Read the output Pulse Width
	return PW; 	// Return the value
}

void setup() {
 // servo pins
  ServoR.attach(A0); //rood
  ServoG.attach(A1); //groen
  ServoB.attach(A2); //blauw
  ServoY.attach(A3); //geel
	// Set S0 - S3 as outputs
	pinMode(S0, OUTPUT);
	pinMode(S1, OUTPUT);
	pinMode(S2, OUTPUT);
	pinMode(S3, OUTPUT);
  // Set Pulse Width scaling to 20%
	digitalWrite(S0,HIGH);
	digitalWrite(S1,LOW);
   // motor
  pinMode(motorR1, OUTPUT);
  pinMode(motorR2, OUTPUT);
  pinMode(motorL1,  OUTPUT);
  pinMode(motorL2, OUTPUT);
  // pwm motors
  pinMode(pmwR, OUTPUT); //Rechts
  pinMode(pmwL, OUTPUT); //Links
  // sonar sensors F
  pinMode(trigPinF, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPinF, INPUT); // Sets the echoPin as an Input

  Serial.begin(9600);
}

void loop() {
  // bestuuring/aandrijving
  digitalWrite(trigPinF, LOW); // sonar sensor berekening naar cm zijkant
  delayMicroseconds(2);
  digitalWrite(trigPinF, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPinF, LOW);
  duration2 = pulseIn(echoPinF, HIGH);
  distance2 = duration2 * 0.034 / 2;

// kleuren sensor en servo's
	redPW = getRedPW();	// Read Red Pulse Width
	currentMillis2 = millis(); // Reset de tijd
  while (millis() - currentMillis2 < delayDuration1) {
  }
	greenPW = getGreenPW(); 	// Read Green Pulse Width
	currentMillis2 = millis(); // Reset de tijd
  while (millis() - currentMillis2 < delayDuration1) {
  }
	bluePW = getBluePW(); 	// Read Blue Pulse Width
  currentMillis2 = millis(); // Reset de tijd
  while (millis() - currentMillis2 < delayDuration1) {
  }
	// Print output to Serial Monitor
	Serial.print("Red PW = ");
	Serial.print(redPW);
	Serial.print(" - Green PW = ");
	Serial.print(greenPW);
	Serial.print(" - Blue PW = ");
	Serial.println(bluePW);
  
  // motors aandrijving
  digitalWrite(motorR1, LOW);
  digitalWrite(motorR2, HIGH);
  digitalWrite(motorL1, LOW);
  digitalWrite(motorL2, HIGH);

if (distance2 >= 30 && distance2 <= 40)  // this means if the boat is between those variables it will do this action
  {
    analogWrite(pmwR, 180);
    analogWrite(pmwL, 180);
  }
if (distance2 < 30)
  {
    analogWrite(pmwR, 255);
    analogWrite(pmwL, 0);
  }
if (distance2 > 40)
  {
    analogWrite(pmwR, 0);
    analogWrite(pmwL, 180);
  }

   //servo move
if (redPW > 120 && greenPW > 120 && bluePW > 120) //is for the sorting system keeps all servos on clossed pos, other if statemetns to open them.
  {
    ServoR.write(0);
    ServoG.write(85);
    ServoB.write(85);
    ServoY.write(0);
   } else {
if (redPW < 80 && greenPW > 80 && bluePW > 80)   //the delay is for keeping the servos open long enough.
  {
    ServoR.write(60);
    currentMillis1 = millis(); // Reset de tijd
    while (millis() - currentMillis1 < delayDuration1) {
  }}
if (greenPW < 100 && redPW > 100 && bluePW > 90) 
  {
    ServoG.write(30);
    currentMillis1 = millis(); // Reset de tijd
    while (millis() - currentMillis1 < delayDuration1) {
  }}
if (bluePW < 97 && redPW > 100 && greenPW > 90)
  {
    ServoB.write(30);
    currentMillis1 = millis(); // Reset de tijd
    while (millis() - currentMillis1 < delayDuration1) {
  }}
if (redPW < 80 && greenPW < 80 && bluePW <105) {
  ServoY.write(60);
    currentMillis1 = millis(); // Reset de tijd
    while (millis() - currentMillis1 < delayDuration1) {
  }}
 }
}

a manual drawing is better than an ugly 3D photorealistic image where we can't see anything :slight_smile:

the GND of the servo battery should also be joining the GND of the Arduino
image

can you post a picture of your breadboard? some are cut in the middle and need a strap if you want to use the power rails from both sides of the middle divide (you'll know if this is your case because the blue and red lines are interrupted where the rail stops)

i use this one. all lines ar conected if i saw it correct. checked it from the bottom i can see the metal lines. am dont have acces to the boat atm so cant post a picture till tommorow.
image