I'm working on a code where the moment a coordinate is received through the x and y variables, it maps them from 0 to 1023 to 0 to 180. This then gets used written to a servo to move accordingly.
//Below handles the movement, so far i'm just working on the x-axis of movement. But for some reason it just does not want to move or work.
void onDetectTarget() {
x = map(x, 0, 1023, 0, 180);
y = map(y, 0, 1023, 0, 180);
if (movement == true) {
for (pos = 0; pos <= x; pos+=1) {
myservo.write(pos);
delay(15);
movement = false;
pos = 0;
}
}
}
//Below code handles the capturing of values, it works very well. Note that it's a piece from a bigger conditional statement.
else if (received_str[0] == '(' ) {
Serial.println("Coordinates Received, Ready to Delete Target!");
movement = true;
int r = sscanf(received_str.c_str(), "(%d, %d)", &x, &y);
Serial.print("X: ");
Serial.println(x);
Serial.print("Y: ");
Serial.println(y);
Whenever I actually run the code, the servo actually never moves ignoring the fact that it moves to the middle on its start-up(servo works normally when using sweep example, I also defined and included servo modules).
Where did I go wrong here? Why does it not want to work? Did I map it wrong? The values being received are bigger than 180, hence me wanting to map them from 0 to 180 due to it being the limit of my servo.
Extra question: Can I map from -90 to 90?
I think you need those last two statements outside your for() loop. Your current code continually sets pos to zero and then writes that value to your servo which makes that in infinite loop.
Oh damn i did not even realise the infinite loop, thank you guys so much for pointing it out.
One extra issue though. My code basically works around receiving numbers over i2c. This particular code works around receiving coordinates over from Python(Pi as Master) to the slave(Arduino) meaning that they change depending on whatever happens on the Pi.
Currently though, the coordinates just stay the same, e.g. 90, 40. Yet whenever the Arduino receives the numbers, the loop seems to reset and has the servo reset its position just to move to the same spot again. Is there an extra piece of code that I've overlooked or?
Worked on it after posting the question, but I did try and make something where it would store an old value of both the x and y variables, wait, then compare to see if any differences were detected. Unfortunately, this did not work.
bool constant = false;
// Rest of code
void statusCodes() {
if (received_str == "1") {
Serial.println("Raspberry Pi - Connection Established");
} else if (received_str == "2") {
Serial.println("Raspberry Pi - Data Received");
} else if (received_str == "100") {
Serial.println("Raspberry Pi - Status OK");
} else if (received_str[0] == '(' ) {
Serial.println("Coordinates Received, Ready to Delete Target!");
if (constant == true) { // checks if this constant boolean is true
movement = false;
} else {
movement == true;
}
int r = sscanf(received_str.c_str(), "(%d, %d)", &x, &y);
Serial.print("X: ");
Serial.println(x);
Serial.print("Y: ");
Serial.println(y);
}
}
void onDetectTarget() {
x = map(x, 0, 1023, 0, 180);
y = map(y, 0, 1023, 0, 180);
if (movement == true) {
for (pos = 0; pos <= x; pos += 1) {
myservo.write(pos);
delay(15);
}
movement = false; // corrected
pos = 0; // corrected
}
}
void compareOldNew() {
x_old = x;
y_old = y;
delay(900);
if (x == x_old && y == y_old) {
constant = true;
} else {
constant = false;
}
}
When this function is called constant will always be set to true...unless x and y are being modified in an interrupt. This is why it would help to see the rest of the code.
// Include the Wire library for I2C
#include <Wire.h>
#include <Servo.h>
Servo myservo;
// Definition of H Bridge, LED pins and integers, note that these are here for test purposes and may be controlled using I2C.
String received_str = "";
int toSend = 1;
int x, y, ammo, mapper, x_old, y_old;
int pos, ypos = 0;
bool flag, constant, trigger, movement = false;
void setup() {
myservo.attach(2);
// Join I2C bus as slave with address 8
Wire.begin(0x8);
// Call receiveEvent when data received and requestEvent when data is to be sent
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
Serial.begin(9600);
}
// Function that executes whenever data is received from master
void receiveEvent(int howMany) {
while (Wire.available()) { // loop through all but the last
// receive byte as a character, char converts unicode to character and add these characters into string
received_str += (char)Wire.read();
}
}
// Function that sends data to Master (Pi). Unlike receiveEvent, the Wire.available confirmation loop cannot be used as it stops data being sent.
void requestEvent() {
Wire.write(toSend);
}
// Function that deals with status codes to control Arduino
void statusCodes() {
if (received_str == "1") {
Serial.println("Raspberry Pi - Connection Established");
} else if (received_str == "2") {
Serial.println("Raspberry Pi - Data Received");
} else if (received_str == "100") {
Serial.println("Raspberry Pi - Status OK");
} else if (received_str[0] == '(' ) {
Serial.println("Coordinates Received, Ready to Delete Target!");
if (constant == true) {
movement = false;
} else {
movement == true;
}
int r = sscanf(received_str.c_str(), "(%d, %d)", &x, &y);
Serial.print("X: ");
Serial.println(x);
Serial.print("Y: ");
Serial.println(y);
}
}
// Function that deals with startUp, establishing connection between the Pi and the Arduino.
void startUp() {
if (flag == false) {
toSend = 1;
delay(3000); // delay of 3 seconds before setting flag to true
flag = true;
}
}
void convertToInt() {
int n = received_str.toInt();
if (n > 0 || received_str[0] == '(') {
//Serial.println(received_str);
received_str = "";
} else {
received_str = "";
}
}
void onDetectTarget() {
x = map(x, 0, 1023, 0, 180);
y = map(y, 0, 1023, 0, 180);
if (movement == true) {
for (pos = 0; pos <= x; pos += 1) {
myservo.write(pos);
delay(15);
}
movement = false;
//pos = 0;
//Code to first map the values of xyz into limit of 255, then have the turret move to target and shoot
}
}
void compareOldNew() {
x_old = x;
y_old = y;
delay(900);
if (x == x_old && y == y_old) {
constant = true;
} else {
constant = false;
}
}
void loop() {
delay(100);
startUp();
toSend = 100;
statusCodes();
convertToInt();
onDetectTarget();
compareOldNew();
}
compareOldNew() will always set constant to true which will result in movement always being set to false which results in onDetectTarget() never moving the servos.
// Function that deals with startUp, establishing connection between the Pi and the Arduino.
void startUp() {
if (flag == false) {
toSend = 1;
delay(3000); // delay of 3 seconds before setting flag to true
flag = true;
}
}
Just put this in setup():
toSend = 1;
delay(3000); // delay of 3 seconds before setting flag to true