title: Python equivalent for byte array transfer from Java (Processing) to C (ardunio) over USBserial
body: <p>As my first foray into programming with python (previous exp only with vba and very basic java), I am trying to replicate some functionality of a GUI application, <a href="https://github.com/osPID/osPID-Front-End" rel="nofollow">osPID Frontend</a>, written in Processing, which communicates with an Arduino sketch, <a href="https://github.com/osPID/osPID-Firmware" rel="nofollow">osPID-Firmware</a>, over USB serial.</p>
  
  <p>The front end takes a float array, converts it to a byte array, and then sends this over the serial link.</p>
  
  <p>I have been trying to test sending a byte array to the device using the following python code:</p>
  
  <pre><code>import serial
  
  def Send_Dash(myPort):
     #To_Controller()
     byteSet = 1,2,3 #bytes(1),bytes(4),bytes(3)
     toSend = bytearray(byteSet)
     myPort.write('5')
     myPort.write('1')
     myPort.write(toSend)
  
  myPort = serial.Serial('/dev/ttyUSB0',9600,8,'N',timeout=None)  # open first serial port
  
  if myPort.isOpen():
     myPort.read(10)
     #typeReq = bytearray('0,0')
     #myPort.write(typeReq)
  
  Send_Dash(myPort)
  </code></pre>
  
  <p>Unfortunately which I can connect ok, I don't seem to be able to send any successful commands. I'd like to come up with some generic function I can use to send commands to the arduino (either by replicating the Processing code in python, or doing away with the byte array structure entirely (if possible). The original code was written to allow values such as 300000 and 0.000001 to the device. I will be unlikely to send anything greater than 300, or with decimals below 0.001, but as I hope to release this open source, others might.</p>
  
  <p>For reference, the relevant arduino and Processing functions are below:</p>
  
  <p>The function which converts the float array to a byte array is:</p>
  
  <pre><code>byte[] floatArrayToByteArray(float[] input)
  {
    int len = 4*input.length;
    int index=0;
    byte[] b = new byte[4];
    byte[] out = new byte[len];
    ByteBuffer buf = ByteBuffer.wrap(b);
    for(int i=0;i&lt;input.length;i++)
    {
      buf.position(0);
      buf.putFloat(input[i]);
      for(int j=0;j&lt;4;j++) out[j+i*4]=b[3-j];
    }
    return out;
  }
  </code></pre>
  
  <p>An example of one of the functions which packs the data is:</p>
  
  <pre><code>// Sending Floating point values to the arduino
  // is a huge pain. if anyone knows an easier
  // way please let know. the way I'm doing it:
  // - Take the 6 floats we need to send and
  // put them in a 6 member float array.
  // - using the java ByteBuffer class, convert
  // that array to a 24 member byte array
  // - send those bytes to the arduino
  void Send_Dash()//To_Controller()
  {
  
  
    float[] toSend = new float[3];
    toSend[0] = float(SPField.getText());
    toSend[1] = float(InField.getText());
    toSend[2] = float(OutField.getText());
  
    Byte a = (AMLabel.valueLabel().getText()=="Manual")?(byte)0:(byte)1;
    byte identifier = 1;
    myPort.write(identifier);
    myPort.write(a);
    myPort.write(floatArrayToByteArray(toSend));
  } 
  </code></pre>
  
  <p>A more simple function is:</p>
  
  <pre><code>void Run_Profile()
  {
  
    byte[] toSend = new byte[2];
    toSend[0]=8;
    toSend[1]=1;
    myPort.write(toSend);
  }
  </code></pre>
  
  <p>The byte array is made into a union:</p>
  
  <pre><code>boolean ackDash = false, ackTune = false;
  union { // This Data structure lets
    byte asBytes[32]; // us take the byte array
    float asFloat[8]; // sent from processing and
  } // easily convert it to a
  foo; // float array
  </code></pre>
  
  <p>And read by SerialReceive(), which takes action based on the data:</p>
  
  <pre><code>void SerialReceive()
  {
  
    // read the bytes sent from Processing
    byte index=0;
    byte identifier=0;
    byte b1=255,b2=255;
    boolean boolhelp=false;
  
    while(Serial.available())
    {
      byte val = Serial.read();
      if(index==0){
        identifier = val;
        Serial.println(int(val));
      }
      else
      {
        switch(identifier)
        {
        case 0: //information request
          if(index==1) b1=val; //which info type
          else if(index==2)boolhelp = (val==1); //on or off
          break;
        case 1: //dasboard
        case 2: //tunings
        case 3: //autotune
          if(index==1) b1 = val;
          else if(index&lt;14)foo.asBytes[index-2] = val;
          break;
        case 4: //EEPROM reset
          if(index==1) b1 = val;
          break;
        case 5: //input configuration
          if (index==1)InputSerialReceiveStart();
           InputSerialReceiveDuring(val, index);
          break;
        case 6: //output configuration
          if (index==1)OutputSerialReceiveStart();
          OutputSerialReceiveDuring(val, index);
          break;
        case 7: //receiving profile
          if(index==1) b1=val;
          else if(b1&gt;=nProfSteps) profname[index-2] = char(val);
          else if(index==2) proftypes[b1] = val;
          else foo.asBytes[index-3] = val;
  
          break;
        case 8: //profile command
          if(index==1) b2=val;
          break;
        default:
          break;
        }
      }
      index++;
    }
  
    //we've received the information, time to act
    switch(identifier)
    {
    case 0: //information request
      switch(b1)
      {
      case 0:
        sendInfo = true;
        sendInputConfig=true;
        sendOutputConfig=true;
        break;
      case 1:
        sendDash = boolhelp;
        break;
      case 2:
        sendTune = boolhelp;
        break;
      case 3:
        sendInputConfig = boolhelp;
        break;
      default:
        break;
      }
      break;
    case 1: //dashboard
      if(index==14 &amp;&amp; b1&lt;2)
      {
        setpoint=double(foo.asFloat[0]);
        //Input=double(foo.asFloat[1]); //Not used
        if(b1==0) 
        { 
          output=double(foo.asFloat[2]);
        } 
      }
      break;
    case 2: //Tune
      if(index==14 &amp;&amp; (b1&lt;=1))
      {
        kp = double(foo.asFloat[0]); //
        ki = double(foo.asFloat[1]); //
        kd = double(foo.asFloat[2]); //
      }
      break;
    case 3: //ATune
      if(index==14 &amp;&amp; (b1&lt;=1))
      {
        aTuneStep = foo.asFloat[0];
        aTuneNoise = foo.asFloat[1];
        aTuneLookBack = (unsigned int)foo.asFloat[2];
      }
      break;
    default:
      break;
    }
  }
  </code></pre>
  
  <hr>
  
  <p>Edit: </p>
  
  <p>Sorry Lesto, yes I did read the duplicate answers, but I've only just figured out how to use struct.pack (I think!).</p>
  
  <p>It appears that the existing Processing code packs (up to) 6 floats into a 32 byte array, using ByteBuffer. 6 floats is 24 bytes using struct.pack - although I gather I can pad this out by adding 1s and 0s into the format string, provided I know where they should go?</p>
  
  <p>Following the comments by lesto, I have had another try (but still not quite there).</p>
  
  <pre><code>import struct
  import serial
  from array import array
  
  def packByteArray(formatToSend):
     bytesToSend = bytearray()
     #bytesToSend.extend(struct.pack('@fffff',1,0,20,0,10) #Different result?
     bytesToSend.extend(struct.pack(formatToSend,1)) #request Type
     bytesToSend.extend(struct.pack(formatToSend,0)) #identifier
     bytesToSend.extend(struct.pack(formatToSend,20)) #Setpoint
     bytesToSend.extend(struct.pack(formatToSend,0))  #Input
     bytesToSend.extend(struct.pack(formatToSend,10)) #Output
     return bytesToSend
  
  def main():   
      myPort = serial.Serial('/dev/ttyUSB0',9600,8,'N',timeout=None)
      #Check if port is open, and if so, send the byta array.
      if myPort.isOpen():
          thisVar = packByteArray('&gt;f')
          print len(thisVar) 
          myPort.write(thisVar)
  
  if __name__ == '__main__':
      main()
  </code></pre>