Anyone here good at Python?

If you say so.


Python math (dodgy last digit rounding):
 

Attachments

  • pym.jpg
    pym.jpg
    42.6 KB · Views: 135
Last edited:
Found a link you might find interesting.

Introduction to Python Serial Ports | PIC | Maker Pro


while(1):

# Wait until there is data waiting in the serial buffer
if(serialPort.in_waiting > 0):

# Read data out of the buffer until a carraige return / new line is found
serialString = serialPort.readline()

# Print the contents of the serial data
print(serialString.decode('Ascii'))

# Tell the device connected over the serial port that we recevied the data!
# The b at the beginning is used to indicate bytes!
serialPort.write(b"Thank you for sending data \r\n")
 
If you say so.


Python math (dodgy last digit rounding):
No, standard IEEE double float semantics - Python shows 17 digits of precision,
whereas double floats have about 16.5 digits precision. Nearly all computer languages use IEEE floating point numbers, so its not a Python-specific issue.

If you want more precision with a floating point number there are modules that can do it.

Basically there are Python modules for pretty much anything. Its extremely heavily used in science and data science with good reason.
 
Yes, I was half joking about pythons rounding and after >20 years in science technical support I am aware of how ubiquitous python is. Though MS Calculator gives me > 30 digits and it gets the rounding of the least significant digit right, so for on-the-fly paper calcs the basic python shell looses badly :fight:

Anyway, after having trawled through way more than what I should have needed to due to the generally crappy nature of python documentation (just my opinion) I have had my first proper script doing useful work for a couple of days now.

Is there a better (more elegant) way to prepare a mutable variable to make it work with ser.write than sticking it into an array?



Code:
# Set up RS-232 serial port

import serial
ser = serial.Serial()
ser.port = 'COM5'                    # Check port number (COM1, COM2, etc) in Device Manager and set accordingly.  
ser.baudrate = 19200
ser.bytesize = 8
ser.parity = 'N'
ser.stopbits = 1


pixels=0
lines=0
address=0
data=0


f = open('640x480_24_bit_colour_image_02.bin', 'rb')    # Open image file as a binary for reading
d = f.read()                                            # Convert image file into a string


ser.open()                                              # Open serial port


for lines in range(480):


    while pixels < 640:

        address = (lines * 1920) + (pixels * 3)
        data = 0

    # Read pixel data from binary

        blue=(d[address])
        green=(d[address+1])
        red=(d[address+2])

        # Convert 24-bit colour RGB to single-byte 6-bit colour

        x = red&64 !=0
        if x == 1:
            data |= (1<<0)
    
        x = red&128 !=0
        if x == 1:
            data |= (1<<1)
    

        x = green&64 !=0
        if x == 1:
            data |= (1<<2)
    
        x = green&128 !=0
        if x == 1:
            data |= (1<<3)


        x = blue&64 !=0
        if x == 1:
            data |= (1<<4)
    
        x = blue&128 !=0
        if x == 1:
            data |= (1<<5)
    

        # Send pixel colour byte over serial port     

        element=[data]     
        a_var=bytearray(element)  
        ser.write(a_var[0:1])      


        print("Pixel=",pixels,"Line=",lines,"Address=",address,"Data=",data)


        pixels += 1

    else:
        pixels = 0            

 
ser.close()
 
Last edited:
Is there a better (more elegant) way to prepare a mutable variable to make it work with ser.write than sticking it into an array?

Code:
        # Send pixel colour byte over serial port     

        element=[data]     
        a_var=bytearray(element)  
        ser.write(a_var[0:1])

That can be reduced to:

Code:
        variable=bytearray([data])  
        ser.write(variable[0:1])
That sends the hex value of data. I can't find a specifier to use in ser.write to identify data as either a hex or int8. So far I can only get ser.write to recognize it as such if it's put into an array.
 
Last edited:
Use a numpy byte array perhaps, as they implement the buffer protocol.

Code:
import numpy as np

length = ....
vec = np.zeros([length], btype = np.int8)
vec[..] = ...  # write values into the array

with serial.Serial ("COM5", baudrate=19200, parity='N'. stopbits=1, bytesize=8) as port:
    port.write (vec)