0

I have been trying to send a value from a Python program via serial to an Arduino, but I have been unable to get the Arduino to store and echo back the value to Python. My code seems to match that I've found in examples online, but for whatever reason, it's not working.

I am using Python 3.5 on Windows 10 with an Arduino Uno. Any help would be appreciated.

Arduino code:

void readFromPython() {
  if (Serial.available() > 0) {
    incomingIntegrationTime = Serial.parseInt();
    // Collect the incoming integer from PySerial
    integration_time = incomingIntegrationTime;
    Serial.print("X");
    Serial.print("The integration time is now ");
    // read the incoming integer from Python:
    // Set the integration time to what you just collected IF it is not a zero
    Serial.println(integration_time);
    Serial.print("\n");
    integration_time=min(incomingIntegrationTime,2147483648);
    // Ensure the integration time isn't outside the range of integers
    integration_time=max(incomingIntegrationTime, 1);
    // Ensure the integration time isn't outside the range of integers
  }
}

void loop() {
  readFromPython();
  // Check for incoming data from PySerial
  delay(1);
  // Pause the program for 1 millisecond
}

Python code: (Note this is used with a PyQt button, but any value could be typed in instead of self.IntegrationTimeInputTextbox.text() and the value is still not receieved and echoed back by Arduino).

def SetIntegrationTime(self):
    def main():
        #    global startMarker, endMarker
        #This sets the com port in PySerial to the port with the Genuino as the variable arduino_ports
        arduino_ports = [
            p.device
        for p in serial.tools.list_ports.comports()
        if 'Genuino' in p.description
        ]
        #Set the proper baud rate for your spectrometer
        baud =  115200
        #This prints out the port that was found with the Genuino on it
        ports = list(serial.tools.list_ports.comports())
        for p in ports:
            print ('Device is connected to: ', p)
        # --------------------------- Error Handling ---------------------------
        #Tell the user if no Genuino was found
        if not arduino_ports:
            raise IOError("No Arduino found")
        #Tell the user if multiple Genuinos were found
        if len(arduino_ports) > 1:
            warnings.warn('Multiple Arduinos found - using the first')
        # ---------------------------- Error Handling ---------------------------
    #=====================================
        spectrometer = serial.Serial(arduino_ports[0], baud)
        integrationTimeSend = self.IntegrationTimeInputTextbox.text()
        print("test value is", integrationTimeSend.encode())
        spectrometer.write(integrationTimeSend.encode())
        for i in range(10): #Repeat the following 10 times
            startMarker = "X"
            xDecoded = "qq"
            xEncoded = "qq"
            while xDecoded != startMarker:    #Wait for the start marker (X))
                xEncoded = spectrometer.read() #Read the spectrometer until 'startMarker' is found so the right amound of data is read every time
                xDecoded = xEncoded.decode("UTF-8");
                print(xDecoded);
            line = spectrometer.readline()
            lineDecoded = line.decode("UTF-8") 
            print(lineDecoded)
    #=====================================
        spectrometer.close()
    #===========================================

#WaitForArduinoData()
    main()

1 Answer 1

1

First, this is a problem:

incomingValue = Serial.read();   

Because read() returns the first byte of incoming serial data reference. On the Arduino the int is a signed 16-bit integer, so reading only one byte of it with a Serial.read() is going to give you unintended results.

Also, don't put writes in between checking if data is available and actual reading:

 if (Serial.available() > 0) {
    Serial.print("X");                  // Print your startmarker
    Serial.print("The value is now ");
    incomingValue = Serial.read(); // Collect the incoming value from 

That is bad. Instead do your read immediately as this example shows:

    if (Serial.available() > 0) {
            // read the incoming byte:
            incomingByte = Serial.read();

That's two big issues there. Take care of those and let's take a look at it after those fundamental issues are corrected.

PART 2

Once those are corrected, the next thing to do is determine which side of the serial communication is faulty. Generally what I like to do is determine one side is sending properly by having its output show up in a terminal emulator. I like TeraTerm for this.

Set your python code to send only and see if your sent values show up properly in a terminal emulator. Once that is working and you have confidence in it, you can attend to the Arduino side.

Sign up to request clarification or add additional context in comments.

7 Comments

Fixed the two mentioned problems: I've implemented Serial.parseInt() instead of Serial.read(), so it's able to acquire the entire integer sent from Python instead of just the first byte, but it's still not working. The Arduino code has been updated above to reflect this change.
Great so now it's time to (1) upvote the helpful answer and (2) decide which side -- sender or receiver -- you want to attend to first. Divide and conquer. What do you know is working right, and why? Do you know the python side is right?
I'd like to know if the value is being sent from Python properly, then I'd like to know if the Arduino is receiving it properly.How would one check whether Python is sending the value properly without having the Arduino read it and return the value? I already have other Python code that is properly allowing data to be received from the Arduino (from a sensor), so I know communication is working properly.
@AggroCrag So print("test value is", integrationTimeSend.encode()) shows what you want? And incomingIntegrationTime is now defined as long? Remember parseInt() returns a long which is a signed 32-bit integer on Arduino.
@AggroCrag Use a trusted terminal emulator. See the updated answer for more detail.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.