Trying to generate heatmap off of an array of float values. Getting an index out of bounds error...

edited March 2018 in Arduino

Edit: Okay I was messing around with initializing "list", and I put

String[] list = new String[64]

Then to test it I had it print out the length of list

println(list.length);

And it prints 1 for the first hundred lines or so then it changes to 24?? Not sure why that is happening...

So my processing code below receives 64 float values from the arduino code. The processing uses linear interpolation equations blah blah to calculate colors for the heat map it generates (I've tested it, it works with a predefined array). What I'm trying to do is fill my 8x8 array from the serial port (the 64 values being sent), but when I run it I get the error on line 45

ArrayIndexOutOfBoundsException: 1

But it used to come out as 5, not sure why it changed to 1. I don't know why this happens, Any help would be great, Thanks!

Arduino:

#include <Wire.h>
#include <Adafruit_AMG88xx.h>

Adafruit_AMG88xx amg;

float pixels[AMG88xx_PIXEL_ARRAY_SIZE];

float maxt = 80.00;
float mint = 0.00;
float newmax = 8.00;
float newmin = 0.00;
float a = (newmax - newmin) / (maxt - mint);

void setup() {
  Serial.begin(9600);

  bool status;

  // default settings
  status = amg.begin();
  if (!status) {
    Serial.println("Could not find a valid AMG88xx sensor, check wiring!");
    while (1);
  }



  delay(100); // let sensor boot up
}


void loop() {
  //read all the pixels
  amg.readPixels(pixels);


  for (int i = 1; i <= AMG88xx_PIXEL_ARRAY_SIZE; i++) {
    Serial.print(pixels[i - 1] / 10.0, 3);
    Serial.print(',');
  }
  Serial.println();
  //delay a second
  delay(100);
}

Processing:

import processing.serial.*;

Serial myPort;
String myString;
String[] list;
int m = 0;

int r = 8;  // number of rows in input array
int c = 8;  // number of columns in input array
int t = 300;  // parameter (array resize factor)
int rows = (r-1)*t;  // height of the heat map
int cols = (c-1)*t;  // width of the heat map

float[][] array = new float[r][c];  // input array
float[][] interp_array = new float[rows][cols]; // interpolated array

void settings()
{
  size(cols, rows);
}

void setup()
{
  printArray(Serial.list());
  //open port you are using at the rate you want
  myPort = new Serial(this, Serial.list()[0], 9600);
  myPort.write(65);

  noStroke();
}

void draw()
{
  while (myPort.available() > 0 ) {

    //Expand array size to the number of bytes you expect
    byte[] inBuffer = new byte[1024];
    myPort.readBytesUntil('\n', inBuffer);

    if (inBuffer != null) {
      myString = new String(inBuffer);
      list = split(myString, ',');
      for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
          array[i][j] = float(list[m]);
          m++;
        }
      }
      m=0;
    }
  }
  bilinearInterpolation();  //these are IN the while loop
  applyColor();
}



void bilinearInterpolation() {  // Bi-linear Interpolation algorithm

  for (int i=0; i<r; i++) {
    for (int j=0; j<c; j++) {
      int x = j*t - 1;
      int y = i*t - 1;
      if (x<0)
        x=0;
      if (y<0)
        y=0;
      interp_array[y][x] = array[i][j];
    }
  }

  for (int y=0; y<rows; y++) {
    int dy1 = floor(y/(t*1.0));
    int dy2 = ceil(y/(t*1.0)); 
    int y1 = dy1*t - 1;
    int y2 = dy2*t - 1;
    if (y1<0)
      y1 = 0;
    if (y2<0)
      y2 = 0;
    for (int x=0; x<cols; x++) {
      int dx1 = floor(x/(t*1.0));
      int dx2 = ceil(x/(t*1.0));
      int x1 = dx1*t - 1;
      int x2 = dx2*t - 1;
      if (x1<0)
        x1 = 0;
      if (x2<0)
        x2 = 0;
      float q11 = array[dy1][dx1];
      float q12 = array[dy2][dx1];
      float q21 = array[dy1][dx2];
      float q22 = array[dy2][dx2];

      int count = 0;
      if (q11>0)
        count++;
      if (q12>0)
        count++;
      if (q21>0)
        count++;
      if (q22>0)
        count++;

      if (count>2) {
        if (!(y1==y2 && x1==x2)) {

          float t1 = (x-x1);
          float t2 = (x2-x);
          float t3 = (y-y1);
          float t4 = (y2-y);
          float t5 = (x2-x1);
          float t6 = (y2-y1);

          if (y1==y2) {
            interp_array[y][x] = q11*t2/t5 + q21*t1/t5;
          } else if (x1==x2) {
            interp_array[y][x] = q11*t4/t6 + q12*t3/t6;
          } else {
            float diff = t5*t6;
            interp_array[y][x] = (q11*t2*t4 + q21*t1*t4 + q12*t2*t3 + q22*t1*t3)/diff;
          }
        } else {
          interp_array[y][x] = q11;
        }
      } else {
        interp_array[y][x] = 0;
      }
    }
  }
}

void applyColor() {  // Generate the heat map 

  color c1 = color(0, 0, 255);  // Blue color
  color c2 = color(0, 255, 0);  // Green color
  color c3 = color(255, 0, 0);  // Red color
  color c4 = color(255, 255, 0);  // Yellow color

  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      float value = interp_array[i][j];
      color c;
      float fraction;

      if (value>=1 && value<2) {
        fraction = (value-1)/1.0;
        c = lerpColor(c1, c2, fraction);
      } else if (value>=2 && value<3) {
        fraction = (value-2)/1.0;
        c = lerpColor(c2, c3, fraction);
      } else if (value>=3 && value<5) {
        fraction = (value-3)/2.0;
        c = lerpColor(c3, c4, fraction);
      } else 
      c = c4;
      stroke(c);
      point(j, i);
    }
  }
}

Answers

  • edited March 2018

    [deleted]

  • edited March 2018

    Please does anyone know what could be wrong with my array declarations and usage?

  • Duplicate.

    Please don't post duplicates

  • edited March 2018

    Duplicate just confuse people. And give you multiple conflicting answers. It's always a bad idea.

  • Answer ✓

    Why do you need to write 65 to it?

    but when I run it I get the error on line 45

    The problem is that when you call the split function, you assume the size of list is r x c but this might not be true. The best thing you can do is to ensure you have these many elements to process: if(list.length>=r*c){...}

    Kf

  • kfrajer, that's exactly what I did (albeit I just took the length and then divided it by r and c respectively, getting the same value.) Thank you!!

  • First, reduce your code to an MCVE (although we won't have the hardware to reproduce, it will be easier to read). What do you mean with

    divided it by r and c respectively, getting the same value.

    Show your mcve,

    Kf

  • I'm sorry but I'm not too sure what MCVE is, all that comes up when I google that is some things about credit cards. And by the "divide by r and c" I just meant I took list.length/r, which outputs 8, because list.length is 64 (I know now thats not always true)

Sign In or Register to comment.