Issue has been resolved. Thanks guys. See post: Sending float values from Python to Arduino via serial... Stumped - #13 by Toasty3000 - Project Guidance - Arduino Forum
Hi all, I've hit a roadblock in my latest project.
Short version: I'm trying to receive two float values via usb serial on my Tinyduino, formatted as follows: <01234.56,10987.65>
I'm trying to get my sketch to read these two floats, and update variables with them. (e.g. var1 = 1st float, and var2 = 2nd float)
I'm really not sure how to do this. I have no experience working with serial communication code, and limited experience with Arduino in general. Learning slowly but surely.
Long (detailed) version:
As I mentioned above, I'm sending two floats via serial com port. I'm trying to create a satellite 'pointer,' so I have a Python program running calculations on telemetry data I input, and that program spits out azimuth and elevation in the form of a stepper motor position (# of steps from 0). I then have it write those positions to Arduino via a preselected com port, and it does this every 5 sec to update the positions.
I found some code here that I tried flexing to work with what I have, but I seem to have failed.
I start up Arduino and my Python program, establish the serial connection, confirm the connection, and then Python starts sending data. The problem I have is that my steppers don't move at all. To confirm the problem was somewhere within the serial connection and/or string parsing, I set the position variables to an arbitrary number from within the sketch, which works.
Here is my Python code:
import serial
import time
import msvcrt
import math
from datetime import datetime
import ephem
import struct
COMPORT = int(input("Port number: "))
arduino = serial.Serial("COM{}".format(COMPORT), 9600, timeout = 1)
arduino.port = "COM{}".format(COMPORT)
print ("Opening Serial port...")
time.sleep(2)
print (arduino.readline())
time.sleep(2)
print ("Initialization complete")
degrees_per_radian = 180.0 / math.pi
home = ephem.Observer()
home.lon = '-110.031' # +E
home.lat = '39.978' # +N
home.elevation = 80 # meters
# Always get the latest ISS TLE data from:
# http://spaceflight.nasa.gov/realdata/sightings/SSapplications/Post/JavaSSOP/orbit/ISS/SVPOST.html
iss = ephem.readtle('ISS',
'1 25544U 98067A 17119.54718229 .00016717 00000-0 10270-3 0 9015',
'2 25544 51.6378 280.7424 0005784 109.0002 251.1778 15.53903632 14187'
)
while True:
home.date = datetime.utcnow()
iss.compute(home)
print('iss: altitude %4.1f deg, azimuth %5.1f deg' % (iss.alt * degrees_per_radian, iss.az * degrees_per_radian))
azi = iss.az * degrees_per_radian
elev = iss.alt * degrees_per_radian
azipc = azi / 360
elevabsolute = elev + 90
elevpc = elevabsolute / 180
azistp = str(round(azipc * 15753.846153846153846153846153846, 2)).zfill(8)
elevstp = str(round(elevpc * 7876.923076923076923076923076923, 2)).zfill(8)
command = '<'
command += elevstp
command += ','
command += azistp
command += '>'
arduino.write(b'command')
print (command)
print (arduino.readline())
time.sleep(5)
Here is my Arduino sketch. Unless there's an obvious problem with my Python code, the problem is in here somewhere. Most likely in the segment that's supposed to parse the data.
#include <AccelStepper.h>
#include <string.h>
#include <stdio.h>
#define HALFSTEP 8
// Motor pin definitions
#define motorPin1 8 // IN1 on the ULN2003 driver 1
#define motorPin2 7 // IN2 on the ULN2003 driver 1
#define motorPin3 5 // IN3 on the ULN2003 driver 1
#define motorPin4 6 // IN4 on the ULN2003 driver 1
#define motorPin5 9 // IN1 on the ULN2003 driver 2
#define motorPin6 12 // IN2 on the ULN2003 driver 2
#define motorPin7 11 // IN3 on the ULN2003 driver 2
#define motorPin8 10 // IN4 on the ULN2003 driver 2
// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
AccelStepper stepper2(HALFSTEP, motorPin5, motorPin7, motorPin6, motorPin8);
//#define SOP '<' ////ignore these
//#define EOP '>' ////ignore these
//#define MID ',' ////ignore these
float elevation = 03100.73;
float azimuth = 02502.54;
const byte numChars = 19;
char receivedChars[numChars];
char tempChars[numChars];
char dataFromPC[numChars] = {0};
float elevFromPC = 0.0;
float aziFromPC = 0.0;
boolean newData = false;
void setup() {
Serial.begin(9600);
delay(250);
Serial.write("Arrrre you ready kids?"); //Sends a message to PC to confirm connection
delay(1000);
stepper1.setMaxSpeed(1000.0);
stepper1.setAcceleration(500.0);
stepper1.setSpeed(500);
stepper2.setMaxSpeed(1000.0);
stepper2.setAcceleration(500.0);
stepper2.setSpeed(500);
}
///// ============== Somewhere below is the problem =============================================
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0';
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
void parseData() {
char * strtokIndx;
strtokIndx = strtok(tempChars, ",");
elevFromPC = atof(strtokIndx);
strtokIndx = strtok(NULL, ",");
aziFromPC = atof(strtokIndx);
}
void showParsedData() {
Serial.println(elevation);
Serial.println(azimuth);
}
////////////// ========================== Somewhere above is the problem ==============================
void loop() { // \/ This part of the code works beautifully when I set elevation or azimuth = 12345.67
elevation = elevFromPC;
azimuth = aziFromPC;
stepper1.moveTo(azimuth);
if (stepper1.distanceToGo() != 0) {
stepper2.moveTo(azimuth);
}
if (stepper1.distanceToGo() == 0) {
stepper2.moveTo(elevation);
}
stepper1.run();
stepper2.run();
}
Anything will help at this point, even if it's a general pointer in the right direction. I'm lost