[SOLVED] Use SoftwareSerial data to map a Servo

Hi everyone, I’m doing a project on my Arduino Uno with Software Serial on pins 10 and 11. I have potentiometer data coming in from my Photon(0-1023) and I’m trying to use that data to turn my Servo according to the data. I’ve been cracking at this for a few weeks now and still haven’t been able to get it. Sometimes the motor randomly goes to some abstract spot that I KNOW does not match the potentiometers data and then goes back to its previous position. I can see the data in the serial monitor but it just won’t write to the servo. If it helps any, I tried to serial print potVal but it showed up as 0 even when the Software serial data was different so I think it might be getting the potVal to match the incoming data. Please note that I did include the Software Serial libraries and the servo library, I just took them out for this.
My code is below:

// software serial #1: TX = digital pin 10, RX = digital pin 11
SoftwareSerial portOne(10, 11);


Servo myServo;  
// software serial #2: TX = digital pin 8, RX = digital pin 9
// on the Mega, use other pins instead, since 8 and 9 don't work on the Mega
SoftwareSerial portTwo(8, 9);
int potVal;
int angle;
void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  portOne.begin(9600);
  
myServo.attach(6);
}

void loop()
{
  // By default, the last intialized port is listening.
  // when you want to listen on a port, explicitly select it:
  portOne.listen();
  
  while (portOne.available() > 0) {
   char inByte = portOne.read();
    Serial.write(inByte); 
     int potVal = portOne.read();

  }
Serial.println();
angle = map(potVal, 0, 1023, 0, 180);

delay(300);
 myServo.write(angle);
  delay(150);
}// FYI this is part of the TwoPortReceive from Arduino.

If you need me to clarify I would be happy to do so. Sorry if i’m confusing at all.

Thanks, Jack

Shouldn’t that be,

myServo.write(angle);

@Ric Oh yeah, I guess it should :joy: let me see if that works…

It still doesn’t but thanks for the tip!!

You are correct. Your code for getting potVal from serial input needs to be fixed.

This doesn’t look right. In this code, potVal can only be one character (digit) long.

This should work for receiving the potVal value over serial:

potVal = 0;
String valueInput = "";
while (portOne.available() > 0) {
    valueInput += portOne.read();
}
Serial.println('Read "' + valueInput + '" from Photon.');
potVal = valueInput.toInt()

Also, it would be best to change this to:

if (angle != myServo.read()) {
  myServo.write(angle);
}

So that it only moves the servo if a new value is given via serial, otherwise it would constantly write 0 to the servo because potVal would be 0.

@nrobinson2000, the important question here to ask would have been: “Are you sending the value binary or ASCII?”.
While the OP’s version suggests binary(but misses the extra byte(s)), your proposed code expects ASCII.
If it is binary, the datatype and the endianness of the value need to be determined too.

Well then, I guess OP could send the values from the Photon as an ASCII string.

@ScruffR @nrobinson2000
So… I’m not sure if this is what you intended but this is what shows up in the Serial monitor:
822628206
822628206
822628206
822628206
822628206
822628206
822628206
822628206

And occasionally there’s a long line too:

822628206
822628206
822628206
822649485051131028206

So make your Photon do Serial.println(String(YOUR_VARIABLE_FOR_POT)) to tell the Arduino to move the servo.

EDIT:
Try it.

@nrobinson2000 Well I figured when you say

I’d make it like this

Serial1.println(String(DATA_FOR_POT));

with data being the value being sent. Then an error comes up saying

error: ‘DATA_FOR_POT’ was not declared in this scope

And the error comes up even if I have it the way you suggested it above.

Would you please share your Photon code? It would help you recieve more relevant help.

Sure:

int reading1;
String reading1AsAString;

void setup() {
Particle.subscribe(“sense1”, myHandler);
Serial1.begin(9600);
}

void loop() {

}

void myHandler(const char *eventname, const char *data) {

Serial1.println(data);

}

Then the data to the Arduino via SoftwareSerial.
The data it subscribes to is the pot data(0-1023).

I don’t see any 'analogread’s. How is your Photon supposed to read the potentiometer?

So it uses an additional photon?

It’s not reading the data right there. It’s subscribing to the pot data published by another Photon then sending it to the Arduino via tx/rx. and ground. The data will show show up in the Serial port. I’m just trying to get that data(0-1023) to be applied to the Servo.

It’s a process. :joy:

I see. I think the problem is that the Arduino is not receiving strings properly. Try this code from an earlier post, replacing Serial2 with portOne and adding in your other stuff.

@nrobinson2000

It doesn’t compile…

It shouldn’t. You must edit it to what is necessary for your Arduino’s purpose.

I did edit it, and I take back what I said earlier; I receive the same data as before but the Servo still won’t turn accordingly… I’ll share the code.

#include <SoftwareSerial.h>
// software serial #1: TX = digital pin 10, RX = digital pin 11
SoftwareSerial portOne(10, 11);
#include <Servo.h>

Servo myServo; // create a servo object
// software serial #2: TX = digital pin 8, RX = digital pin 9
// on the Mega, use other pins instead, since 8 and 9 don’t work on the Mega
SoftwareSerial portTwo(8, 9);

String readString = “”;

void parseCommand(String command)
{
if (command == “foo”)
{

}
}

void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}

// Start each software serial port
portOne.begin(9600);

myServo.attach(6);
}

void loop()
{
// By default, the last intialized port is listening.
// when you want to listen on a port, explicitly select it:
portOne.listen();

// while there is data coming in, read it
// and send to the hardware serial port:

while (portOne.available() > 0) {
delay(3);
char c = portOne.read();
readString += c; // Add the character to the string
}
readString.trim();

if (readString.length() > 0) // If a string has been read…
{
Serial.println("Received: " + readString); // Send the parsed string to Serial for debugging
parseCommand(readString); // Do something with the string…
readString = “”; // Clear the string
}

delay(150);
myServo.write(readString);

}

There’s errors on

So the arduino sucessfully recieves the same string as the photon got from subscribing to the other photon?