Search code examples
javaarduinoserial-portprocessing

How to modify arrays in Processing and send them from serial to Arduino?


I have a code that currently takes values from a controller input in Processing, sends those values over serial to an Arduino Uno that sends those values over radio to another Arduino Uno. I am attempting to change format to send an array for better communication and this is my current failed attempt at that

Current processing code

 int status[] = {0, 0, 0, 0, 0}
 void draw
 if (thumblefty > .2)
 {
 status[0]=3;
 }
 if (thumblefty < -.2)
 {
 status[0]=0;
 }
 if (thumbleftx>.2)
 {
 status[0]=1;
 }
 if (thumbleftx<-.2)
 {
 status[1]=2;
 }
 //etc etc on the if statements
 myPort.write(status);
 }

This however produces an error line on the myPort.write that says The function “write()” expects parameters like: “write(byte[])”. I do not wish to send a byte, as I want to do more than 1's and 0's in this array. Even when I do modify the code to make it

byte status[]={0,0,0,0,0}

I do not get the expected results on my receiving arduino

Transmitter code (Arduino)

byte state[4];
void loop
state[4] = Serial.read();
radio.write(&state, sizeof(state));

Receiving code (Arduino)

byte state[4];
void loop
radio.read(&state, sizeof(state));
Serial.println(state[4]);

When the controller is in it's up position, I expect an output on the receiving serial of [3,0,0,0,0], but instead the serial port is full of random integers that have no change based on controller position and are not in a byte or array form

I would like help configuring my processing code to send an array, and help figuring out how I can interpret that array over serial and sending over RF24. The end goal is to have the receiving Arduino be able to look at the values in each position of the array, say

if state[3]==2
{
motor 2 full power
}

And be able to do that for all positions of the array, to have all possible inputs encoded in the array to be deciphered, but I first need my serial port to even receive the array itself


Solution

  • The following source code will send a string of random state values from an integer array in Processing to Arduino as comma separated values; the end of the string is terminated by a line feed. Addendum: Original answer edited to convert array integer to a string prior to writing to Arduino, ie str(myState[i]).

    Processing code:

    import processing.serial.*;
    
    int[] myState = new int[4];
    Serial myPort;
    
    void setup() {
      // Output is in console
      surface.setVisible(false);
      printArray(Serial.list());
     // Set port number for your system
      myPort = new Serial(this, Serial.list()[3], 9600);
    }
    
    void draw() {
      if (frameCount % 60 == 0) {
        myState[0] = int(random(4));
        myState[1] = int(random(4));
        myState[2] = int(random(4));
        myState[3] = int(random(4));
        for (int i = 0; i < myState.length-1; i++) {
          myPort.write(str(myState[i]));
          myPort.write(',');
        }
        myPort.write(str(myState[3]) + '\n');
        printArray(myState);
        println("=============");
      }
       
    }
    

    Alternate Solution: Following source code uses an alternate method of sending array string. It works well with Arduino code which follows. An LED was added to the project to demonstrate that array really is being used on the Arduino side since we can't use Serial Monitor (port is tied up by Processing). You can delete the LED code if you don't want to use it.

    import processing.serial.*;
    
    int[] myState = new int[4];
    Serial myPort;
    String inStr;
    String outStr;
    int x1, x2, x3, x4;
    void setup() {
      // Output is in console
      surface.setVisible(false);
      printArray(Serial.list());
      // Set port number for your system
      myPort = new Serial(this, Serial.list()[3], 9600);
    }
    
    void draw() {
      if (frameCount % 60 == 0) {
        myState[0] = int(random(4));
        myState[1] = int(random(4));
        myState[2] = int(random(4));
        myState[3] = int(random(4));
        outStr = str(myState[0]) + "," + str(myState[1]) + "," + str(myState[2]) + "," + str(myState[3]) + "\n";
        myPort.write(outStr);
        printArray(myState);
        println("=============");
      }   
    }
    
    void serialEvent(Serial p) {
      inStr = p.readStringUntil('\n');
      if (inStr != null) {
        String trimStr = trim(inStr);
        println("receivedBack : " + trimStr);   
    }
    }
    
    

    Arduino Code:

    const int LED = 12;
    
    int myState[4];
    
    String inStr;
    
    void setup() {
      Serial.begin(9600);
      pinMode(LED, OUTPUT);
    }
    
    void loop() {
      if (Serial.available() > 0) {
        inStr = Serial.readStringUntil('\n');
        myState[0] = Serial.parseInt(); 
        Serial.println("state[0]"); 
        myState[1] = Serial.parseInt();
        Serial.println("state[1]"); 
        myState[2] = Serial.parseInt(); 
        Serial.println("state[2]");
        myState[3] = Serial.parseInt();
        Serial.println("state[3]");
      }
      
      if(myState[3] == 2){
        digitalWrite(LED, HIGH); 
        delay(2000);
      } else {
        digitalWrite(LED, LOW);
        delay(2000);
      }
      }