Python-How to add a struct.pack value to an integer that would be sent through the serial port

12,466

You're passing a string literal; you should be passing a value instead, indicated by using the bare name. But you'll need to convert it to an integer before it can be handled.

POS_SERVO = struct.pack('<h', int(posicion))

You should consider validating the input though, to make sure that it's the corect type and within the desired range.

Share:
12,466
Pablo P.
Author by

Pablo P.

Updated on June 05, 2022

Comments

  • Pablo P.
    Pablo P. almost 2 years

    I'm a newbie in python and recently I made a similar question about how to convert a decimal value to an integer with low byte first and then high byte is here and is solved but now I have a problem because I want python to take a decimal value from a raw_input convert it to an integer with low byte first and then high byte and insert it into a 16-bit integer to send it to the serial port to a servo controller (devantech sd84). I've contained the raw_input into a value and then the struc.pack in other value then I put the second value into the 16-bit integer but before this can occurs python returns this error:

        Traceback (most recent call last):
        File "C:/Users/Pablo/Desktop/kdfkldkfgv", line 28, in <module>
        POS_SERVO = struct.pack('<h', 'posicion')
        error: cannot convert argument to integer
    

    Here is the complete code:

        # -*- coding: utf-8 -*-
      import serial
      import time
      import struct
      # Para cambiar de Sistema Operativo cambiar puerto 
      #en la siguiente línea: Win COM# linux /dev/ttyS# /dev/ttyUSB#
      # #=un número asignado por tu sistema.
      port='COM3'
      sync='\xAA\xA0\x55'
      SET_SERVO='\x01'
      GET_SERVO='\x02'
      SET_SPEED='\x03'
      SET_MODE='\x04'
      GET_MODE='\x05'
      SET_AD_CNT='\x06' #Controla el número de canales analógicos.
      GET_AD_CNT='\x07' #Devuelve el número de canales analógicos actuales.
      GET_INPUT='\X08' # Devuelve el estado de una entrada.
      GET_ADC='\X09' #Devuelve el valor de un canal analógico.
      GET_VERSION='\x0A' #Devuelve la versión del procesador seleccionado.
      GET_BULK='\x15' #Usado para test en fábriica.
      TEST='\X16' #Usado para test en fábrica.
      ser = serial.Serial(port, baudrate=115200, bytesize=8, parity='N', stopbits=2,timeout=1)
    
      if ser.isOpen():
    print "Estado del puerto: Correcto."
    print "Procedo a enviar modo del canal 1 y posiciones del mismo."
    posicion = raw_input('Inserta un numero entre 400 y 2200:')
    POS_SERVO = struct.pack('<h', 'posicion')
    ser.write(sync+SET_MODE+'\x01\x01\x19')
    ser.write(sync+SET_SERVO+'\x01\x02'+POS_SERVO)
    time.sleep(1.6) 
    ser.close
    print "Todo el proceso completado correctamente."
    
       else:
    print "El puertito está cerrado"
    
       print "Hasta Luego :D"
    

    For the interest of people who have the same controler I'll explain that 16-bit integer first three bytes are sync (\xAA\xA0\x55) then the type of command SET_SERVO (position) (\x01) then the channel 1-84 for 1 is (\x01) then a byte count in this case 2 (\x02) and the servo position low byte and then the high byte (POS_SERVO) (for example for 1500 \xDC\x05)

    I don't know how to solve it, because it's not an argument in fact it is a value and I don't know how to tell that to python.