Arduino Code - New
Arduino Code - New
// Libraries
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <math.h>
#include <NewPing.h>
#include <PENO_Library.h>
#include <HX711.h>
#pragma endregion
//Sonar variables
const byte TRIGGER = 46, ECHO = 47;
const int MAX_DISTANCE = 400;
//Scale variables
const int LOADCELL_DOUT_PIN = 28;
const int LOADCELL_SCK_PIN = 44;
const float calFac = -401050 / 200;
//Bean variables
const int angleBox1 = 25, angleBox2 = 85, angleBox3 = 140;
const int angles[3] = {angleBox1, angleBox2, angleBox3};
int angleWhite = NULL, angleBrown = NULL, angleBlack = NULL;
int angleBox;
String box1 = "", box2 = "", box3 = "";
int colorBox1[3] = { 0, 0, 0 }, colorBox2[3] = { 0, 0, 0 }, colorBox3[3] = { 0, 0, 0 };
const int WHITE[3] = {48, 82, 88};
const int BROWN[3] = {55, 105, 110};
const int BLACK[3] = {65, 117, 123};
float weightWhite = 0, weightBrown = 0, weightBlack = 0, weight = 0;
String chosenColor = "";
double currentWeight = 0;
#pragma endregion
#pragma endregion Variables
void setup()
{
#pragma region Main setup
// NIET AANPASSEN ------------------------
pwm.begin();
pwm.setOscillatorFrequency(27000000);
pwm.setPWMFreq(SERVO_FREQ);
pinMode(25, OUTPUT);
digitalWrite(25, HIGH);
Serial.begin(9600);
delay(100);
Serial2.begin(115200);
// EINDE "NIET AANPASSEN"
// Setup
pinMode(DC1, OUTPUT);
pinMode(DC2, OUTPUT);
//colorSetup(CS0, CS1, CS2, CS3, CSOUT);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale.set_scale(calFac);
scale.tare();
//Processing
if (command.length()>0)
{
commando = command.substring(0,command.indexOf('/'));
parameters = command.substring(command.indexOf('/')+1);
if(commando == "beans")
chosenColor = parameters;
else if(commando.startsWith("gewicht"))
{
weight = parameters.substring(7, parameters.length()).toFloat();
if(chosenColor == "black")
weightBlack = weight;
else if(chosenColor == "brown")
weightBrown = weight;
else if(chosenColor == "white")
weightWhite = weight;
}
else if(commando == "verify")
dataConfirmed = true;
}
}
if(box == "1")
{
goToAngleLR = angleBox1;
angleBox = angleBox1;
}
else if(box == "2")
{
goToAngleLR = angleBox2;
angleBox = angleBox2;
}
else if(box == "3")
{
goToAngleLR = angleBox3;
angleBox = angleBox3;
}
}
#pragma endregion Data setup
if(test)
weight = 150;
delay(2000);
}
void loop()
{
//Declarations
distance = realDist(sonar.ping_cm(), currentAngleUD);
currentWeight = measureWeight();
t = millis();
//Scanning colors
delay(200);
r = redPW(CS2, CS3, CSOUT);
delay(200);
g = greenPW(CS2, CS3, CSOUT);
delay(200);
b = bluePW(CS2, CS3, CSOUT);
//Changing angles
if(box1 != "" && box2 == "" && box3 == "")
{
goToAngleLR = angleBox2;
}
else if(box1 != "" && box2 != "" && box3 == "")
{
goToAngleLR = angleBox3;
}
}
#pragma endregion color setup
#pragma region fullfilling order
else if(!finished)
{
//Declarations
currentWeight = measureWeight();
goToAngleUD = !(currentWeight >= breakOff * weight) ? angleVert(goToAngleUD) : goToAngleUD;
goToAngleLR = angleHor(currentAngleLR);
delData = t - dataPrev;
delArm = t - prev_arm;
delData2 = t - dataPrev2;
//Processing
currentWeight = measureWeight();
//Print the current weight
Serial.println(currentWeight);
passedGoToAngleUD = passedAngle(goToAngleUD);
//Output
return currentAngle;
}
///
// servoNr is a number corresponding to the port the servo you want to control is connected to
///
void continuousServoControl(uint8_t servoNr, bool way, bool on)
{
//Declarations
short clockOrCounter;
//Processing
clockOrCounter = servoNr == belt2 ? (way ? 200 : 400) : (way ? 400 : 200);
clockOrCounter = !on ? 300 : clockOrCounter;
pwm.setPWM(15 - servoNr, 0, clockOrCounter);
}
///
// Speed is a value between -100 and +100 that roughly corresponds to the actual speed
// The actual speed is 1 of 5 values: CCW fast, CCW slow, stationary, CW slow, CW fast
// -50, 0 and 50 are the switch values for the speeds
///
void DCControl(int8_t speed)
{
//Processing
if (speed < -50)
{
analogWrite(DC1, 255);
analogWrite(DC2, 255);
}
else if (-50 <= speed < 0)
{
analogWrite(DC1, 255);
analogWrite(DC2, 0);
}
else if (0 < speed <= 50)
{
analogWrite(DC1, 0);
analogWrite(DC2, 0);
}
else if (50 < speed)
{
analogWrite(DC1, 0);
analogWrite(DC2, 255);
}
}
#pragma endregion Motor functions
#pragma region Processing functions
///
// This method is used to assign angles to different colors
///
void colorAngleAssignment(short angle)
{
switch(angle)
{
case angleBox1:
box1 = beanAssignment(r, g, b);
angleWhite = angleAssignment("white", angle, angleWhite);
angleBrown = angleAssignment("brown", angle, angleBrown);
angleBlack = angleAssignment("black", angle, angleBlack);
break;
case angleBox2:
box2 = beanAssignment(r, g, b);
angleWhite = angleAssignment("white", angle, angleWhite);
angleBrown = angleAssignment("brown", angle, angleBrown);
angleBlack = angleAssignment("black", angle, angleBlack);
break;
case angleBox3:
box3 = beanAssignment(r, g, b);
angleWhite = angleAssignment("white", angle, angleWhite);
angleBrown = angleAssignment("brown", angle, angleBrown);
angleBlack = angleAssignment("black", angle, angleBlack);
break;
}
}
///
// To calculate the angle of the Up-Down-servo
///
short angleVert(short currentAngle)
{
//Processing
if(distance > 15)
return currentAngle - 20;
else if(distance == 5)
return currentAngle;
else if(distance > 5)
return currentAngle - 1;
else
return currentAngle + 1;
}
///
// To calculate the angle of the Left-Right-servo
///
int angleHor(short currentAngle)
{
//Processing
if(angleBox - currentAngle >= 0)
//Output
return angleBox + 8;
else if(angleBox - currentAngle < 0)
//Output
return angleBox - 6;
}
///
// For assigning RGB values to the boxes
///
void colorAssignment(short angle)
{
//Processing
switch(angle)
{
case angleBox1:
colorBox1[0] = r;
colorBox1[1] = g;
colorBox1[2] = b;
break;
case angleBox2:
colorBox2[0] = r;
colorBox2[1] = g;
colorBox2[2] = b;
break;
case angleBox3:
colorBox3[0] = r;
colorBox3[1] = g;
colorBox3[2] = b;
break;
}
}
///
// Assigning boxes to bean colors
///
String beanAssignment(int R, int G, int B)
{
//Declarations
float deviationWhite = 0, deviationBrown = 0, deviationBlack = 0, minimumDeviation;
int RGB[3] = {R, G, B};
String color;
//Processing
for(byte i = 0; i <= 2; i++)
deviationWhite += pow(RGB[i] - WHITE[i], 2);
for(byte i = 0; i <= 2; i++)
deviationBrown += pow(RGB[i] - BROWN[i], 2);
for(byte i = 0; i <= 2; i++)
deviationBlack += pow(RGB[i] - BLACK[i], 2);
minimumDeviation = minimum(deviationWhite, deviationBrown, deviationBlack);
if(minimumDeviation == deviationWhite)
color = "white";
else if(minimumDeviation == deviationBrown)
color = "brown";
else
color = "black";
//Output
return color;
}
///
// Assgining angles to the colors corresponding to the box they are in
///
int angleAssignment(String color, short angle, short colorAngle)
{
//Declarations
int retAngle = NULL;
//Processing
if(colorAngle == NULL)
{
if(color == box1)
if(angleBox1 == angle)
retAngle = angleBox1;
else if(color == box2)
if(angleBox2 == angle)
retAngle = angleBox2;
else if(color == box3)
if(angleBox3 == angle)
retAngle = angleBox3;
}
else
retAngle = colorAngle;
//Output
return retAngle;
}
///
// Function to measure the weight
///
float measureWeight()
{
//Output
return scale.get_units();
}
///
// Function to calculate the amount of beans in the box
///
void calculateQuantity()
{
//Declarations
byte amount, box;
float currentHeight;
//Processing
if(angleBox == angleBox3)
box = 3;
else if(angleBox == angleBox2)
box = 2;
else if(angleBox == angleBox1)
box = 1;
currentHeight = currentLevel();
//Output
sendQuantity(box, amount);
}
#pragma endregion Processing functions TODO: angleHor, angleVert
#pragma region Wifi functions
///
// Functions for sending data to the application
///
void fromMonitorToApp(String message)
{
sendWifi("MonitorToApp/" + message);
}
///
// Function for decoding signals sent from the application
///
String checkwifi()
{
//Declarations
String command = "";
//Processing
while (Serial2.available())
command = Serial2.readString();
if(command.indexOf(startsequence) > 0)
{
command = command.substring(command.indexOf(startsequence) + startsequence.length());
command = command.substring(0, command.indexOf(stopsequence));
}
//Checking if it is a setup command
else if(command.indexOf(startsequenceSetup) > 0)
{
displayESP32Setup(command);
command = "";
}
else
command = "";
//Output
return command;
}
#pragma endregion Wifi functions
#pragma region Helper functions
///
// Helper function for calculating the level of hte beans
///
float currentLevel()
{
//Processing & Output
return zeroHeight - (distance - sin(goToAngleUD / 180 * PI) * armLength);
}
///
// Minimum helper function
///
float minimum(float x, float y, float z)
{
//Processing
if(x <= y && x <= z)
//Output
return x;
else if(y <= x && y <= z)
//Output
return y;
else
//Output
return z;
}
///
// Helper function to calculate the real distance
///
float realDist(float dist, short angle)
{
//Output
return dist * cos(angle / 180 * PI);
}
///
// Helper function to convert the servo angle into the actual angle
//
short passedAngle(short angle)
{
//Output
return angle + 39;
}
///
// Helper function for sending data over wifi-signal to the application
///
void sendWifi(String message)
{
//Output
Serial2.println(message);
}
///
// Helper function for wifi setup
///
void displayESP32Setup(String command)
{
//Processing
command = command.substring(command.indexOf(startsequenceSetup) + startsequenceSetup.length());
command = command.substring(0, command.indexOf(stopsequenceSetup));
Serial.println(command);
}
#pragma endregion Helper functions
#pragma endregion Functions