int[32][32] stops Teensy 3.1 from working. Array too big? issue with Serial?

Status
Not open for further replies.

Nupky

Member
Hey everyone! I am hoping you can help me.

I am currently working on a project where I am making a multiplexer controlled array of sensors that record pressure applied on a x/y co-ordinates of a multi-touch, pressure sensitive square grid. It stores the analog read value into an array, and with 32 rows and 32 columns crossing over each other, it is an int[32][32] array. The problem is, that when I make the array any bigger than int[10][32], my Teensy 3.1 stops working. I know this because the LED pin dies then and no more data is sent out of the Serial port.

Basically, four analog multiplexers (CMOS 16 channel MUX/DEMUX - CD74HC4067) are used to make the circuit. Two are used to power on/off rows and two are used to read the analog values of the columns. One row is turned on, the columns are read one by one and on completion the row is turned off. Then the next row is turned on and the process repeats until all rows/columns have been read. It simply does scanning for data. It then prints the full array out in a single line of Serial (I am looking for a better solution so I am open to suggestions).

I read this data back in MaxMSP so I can play around with sounds and visualizations. In fact, I thought the ideal way to handle the data would be as a greyscale 32x32 video feed but havent figured out how to get that to work.

So! the question is:
is my int[32][32] array too big for internal memory? too big for the Serial port? Am I missing something code-wise to make it work? and is there a way I can export an int[32][32] array as a video feed (that hopefully MaxMSP can understand)?

Thanks so much for any help!

Code:
Code:
//Mux control pins (Analog Sensing)
int E1_Analog = 8;  //A
int E2_Analog = 7;  //B
int E3_Analog = 6;  //C
int E4_Analog = 5;  //D

int F1_Analog = 4;  //A
int F2_Analog = 3;  //B
int F3_Analog = 2;  //C
int F4_Analog = 1;  //D

// Mux control pins (Digital Controling)
int G1_Digital = 13;  //A
int G2_Digital = 14;  //B
int G3_Digital = 16;  //C
int G4_Digital = 15;  //D

int H1_Digital = 9;   //A
int H2_Digital = 10;  //B
int H3_Digital = 12;  //C
int H4_Digital = 11;  //D


// Mux "SIG" pin - The single pin that reads or writes a value to the other 16 pins
int SIG_pin_Analog_E = A8;
int SIG_pin_Analog_F = A9;


// Holds the Array of data gathered
// columns are digital and rows are analog reading
const int Grid_Analog_Half = 32;
const int Grid_Digital = 32;

int pinRowColumn[Grid_Analog_Half][Grid_Digital] = {
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};

// Accelerometer info
const int ypin = A3;                  // y-axis
const int xpin = A4;                  // x-axis

//#define CPU_8MHz       0x01


void setup(){
  // Analog (Scanning) Pins setup
  pinMode(E1_Analog, OUTPUT); 
  pinMode(E2_Analog, OUTPUT); 
  pinMode(E3_Analog, OUTPUT); 
  pinMode(E4_Analog, OUTPUT); 
  
  pinMode(F1_Analog, OUTPUT); 
  pinMode(F2_Analog, OUTPUT); 
  pinMode(F3_Analog, OUTPUT); 
  pinMode(F4_Analog, OUTPUT); 
  
  // Digital (Controling) Pins setup
  pinMode(G1_Digital, OUTPUT); 
  pinMode(G2_Digital, OUTPUT); 
  pinMode(G3_Digital, OUTPUT); 
  pinMode(G4_Digital, OUTPUT); 
  
  pinMode(H1_Digital, OUTPUT); 
  pinMode(H2_Digital, OUTPUT); 
  pinMode(H3_Digital, OUTPUT); 
  pinMode(H4_Digital, OUTPUT); 

  // Initiate
  digitalWrite(E1_Analog, LOW); 
  digitalWrite(E2_Analog, LOW); 
  digitalWrite(E3_Analog, LOW); 
  digitalWrite(E4_Analog, LOW); 
  
  digitalWrite(F1_Analog, LOW); 
  digitalWrite(F2_Analog, LOW); 
  digitalWrite(F3_Analog, LOW); 
  digitalWrite(F4_Analog, LOW); 
  
  digitalWrite(G1_Digital, LOW); 
  digitalWrite(G2_Digital, LOW); 
  digitalWrite(G3_Digital, LOW); 
  digitalWrite(G4_Digital, LOW);

  digitalWrite(H1_Digital, LOW); 
  digitalWrite(H2_Digital, LOW); 
  digitalWrite(H3_Digital, LOW); 
  digitalWrite(H4_Digital, LOW);
    
  Serial.begin(115200);
}

void loop(){ 
  // Turn on each Digital pin individually to measure each analog row
  // e.g. D0 = HIGH, measure all analog. Then D1 = HIGH, measure all analog... etc
  // Scanning
  for (int i = 0; i < Grid_Digital; i++) {  //32
    writeMuxDigital(i);
        
    if ((i % 2) == 1) {
      for (int j = 0; j < Grid_Analog_Half; j++) {  //16
          pinRowColumn[j][i] = readMuxAnalog(j*2); // times 2 so that all even ports are selected.
      }
    }
    else {
        for(int j = 0; j < Grid_Analog_Half; j++) {  //16
            pinRowColumn[j][i] = readMuxAnalog((j*2)+1); // times 2 +1 so that all odd ports are selected.
        }
      }
  }

    // Package BEGIN Check Values
    Serial.print("233 0 233 ");    
      
    // Send one packet of Data over Serial.
    for(int i = 0; i < Grid_Digital; i++) {
      for (int j = 0; j < Grid_Analog_Half; j++) {
        Serial.print(pinRowColumn[j][i]);
        Serial.print(" ");
      } 
    }
    
    // Acclerometer data X & Y
    Serial.print(analogRead(xpin));
    Serial.print(" ");
    Serial.print(analogRead(ypin));
    
    // Package END Check Values
    Serial.println(" 244 0 244");
    
    delay(20);
}


int readMuxAnalog(int channel){
  int controlPin_E[] = {E1_Analog, E2_Analog, E3_Analog, E4_Analog};
  int controlPin_F[] = {F1_Analog, F2_Analog, F3_Analog, F4_Analog};

  int muxChannel[16][4]={
    {LOW, LOW, LOW, LOW}, //channel 0
    {HIGH,LOW, LOW, LOW}, //channel 1
    {LOW, HIGH,LOW, LOW}, //channel 2
    {HIGH,HIGH,LOW, LOW}, //channel 3
    {LOW, LOW, HIGH,LOW}, //channel 4
    {HIGH,LOW, HIGH,LOW}, //channel 5
    {LOW, HIGH,HIGH,LOW}, //channel 6
    {HIGH,HIGH,HIGH,LOW}, //channel 7
    {LOW, LOW, LOW,HIGH}, //channel 8
    {HIGH,LOW, LOW,HIGH}, //channel 9
    {LOW, HIGH,LOW,HIGH}, //channel 10
    {HIGH,HIGH,LOW,HIGH}, //channel 11
    {LOW, LOW,HIGH,HIGH}, //channel 12
    {HIGH,LOW,HIGH,HIGH}, //channel 13
    {LOW,HIGH,HIGH,HIGH}, //channel 14
    {HIGH,HIGH,HIGH,HIGH}  //channel 15
  };

  //loop through the 4 SIG pins to program Multiplexer
  for(int i = 0; i < 4; i ++){
    if (channel < (Grid_Analog_Half/2)) {
      digitalWrite(controlPin_E[i], muxChannel[channel][i]);
    }
    else {
      digitalWrite(controlPin_F[i], muxChannel[channel][i]);
    }
  }

  //read the value at the SIG pin
  //return the value
  if (channel < (Grid_Analog_Half/2)) {
      int val = analogRead(SIG_pin_Analog_E);;
      val = val/4; // scales 1024 to 256
      return val;
    }
    else {
      int val = analogRead(SIG_pin_Analog_F);
      val = val/4; // scales 1024 to 256
      return val;
    }
}


int writeMuxDigital(int channel){
  int controlPin_G[] = {G1_Digital, G2_Digital, G3_Digital, G4_Digital};
  int controlPin_H[] = {H1_Digital, H2_Digital, H3_Digital, H4_Digital};

  int muxChannel[16][4]={
    {LOW, LOW, LOW, LOW}, //channel 0
    {HIGH,LOW, LOW, LOW}, //channel 1
    {LOW, HIGH,LOW, LOW}, //channel 2
    {HIGH,HIGH,LOW, LOW}, //channel 3
    {LOW, LOW, HIGH,LOW}, //channel 4
    {HIGH,LOW, HIGH,LOW}, //channel 5
    {LOW, HIGH,HIGH,LOW}, //channel 6
    {HIGH,HIGH,HIGH,LOW}, //channel 7
    {LOW, LOW, LOW,HIGH}, //channel 8
    {HIGH,LOW, LOW,HIGH}, //channel 9
    {LOW, HIGH,LOW,HIGH}, //channel 10
    {HIGH,HIGH,LOW,HIGH}, //channel 11
    {LOW, LOW,HIGH,HIGH}, //channel 12
    {HIGH,LOW,HIGH,HIGH}, //channel 13
    {LOW,HIGH,HIGH,HIGH}, //channel 14
    {HIGH,HIGH,HIGH,HIGH}  //channel 15
  };

  //loop through the 4 SIG pins to program Multiplexer
  for(int i = 0; i < 4; i ++){
    if (channel < (Grid_Digital/2)) {
      digitalWrite(controlPin_G[i], muxChannel[channel][i]);
    }
    else {
      digitalWrite(controlPin_H[i], muxChannel[channel][i]);
    }      
  }
}
 
Last edited:
Why do you have muxChannel and the controlPin arrays local to the writeMuxDigital and readMuxAnalog functions?
It would also use less memory if you declared them to be unsigned char instead of int.

It is also best to post your code in code tags rather than a quote. You can edit your post and change the quote tags to code tags.

Pete
 
You will also find some useful info if you set your preferences to show verbose info during compilation. There are a few warnings that you really need to check out:
Code:
sketch_mar11a.ino: In function 'int writeMuxDigital(int)':
sketch_mar11a.ino:214:1: warning: no return statement in function returning non-void [-Wreturn-type]
sketch_mar11a.ino: In function 'int readMuxAnalog(int)':
sketch_mar11a.ino:163:49: warning: array subscript is above array bounds [-Warray-bounds]
sketch_mar11a.ino: In function 'int writeMuxDigital(int)':
sketch_mar11a.ino:211:49: warning: array subscript is above array bounds [-Warray-bounds]

Pete
 
I doubt your problem is with your array size. It is only about 2k.

Just a guess here, but your problem may be other things, such as this:

Code:
// Send one packet of Data over Serial.
for(int i = 0; i < Grid_Digital; i++) {
for (int j = 0; j < Grid_Analog_Half; j++) {
Serial.print(pinRowColumn[j][i]);
Serial.print(" ");
}
}

You are basically flooding Serial with about ~3k of data all at once (1024 prints of about ~3chars depending on number). I haven't studied how Serial buffers its input, but you might try slowing that down a bit. Maybe as a test, print a chunk, give it a Serial.send_now(), then a delay, then repeat.
 
serial output as OP coded should work ok. It'll just block if the output buffer fills. The receiving end of the serial link must keep up though.
Better to have some sort of flow control protocol such as send x amount then wait for a response of "got it all OK, next hunk please"
 
One other thing, you might want to pull these type of variables out of the function calls, make them global and put "const" in front of them. As written it looks like they are reallocated on the stack for every function call. Just a time optimization.

Code:
int controlPin_E[] = {E1_Analog, E2_Analog, E3_Analog, E4_Analog};
int controlPin_F[] = {F1_Analog, F2_Analog, F3_Analog, F4_Analog};
int muxChannel[16][4] = ...
 
One other thing, you might want to pull these type of variables out of the function calls, make them global and put "const" in front of them. As written it looks like they are reallocated on the stack for every function call. Just a time optimization.

Some embedded environments run with a fairly small stack. If the Teensy 3.0 does not have a stack with at least 2k of space at the time the function is called, it might overwrite data, such as data for malloc. I don't know if the Teensy 3.x has a small stack or not, but it would be worth it to try making them const (otherwise as nox771 mentions, the compiler has to recreate the array at runtime).

In addition, you should make E1_Analog, etc. const as well (you will need to do this if you move the arrays out as globals).

<edit>
Here is a quick stab at moving things to being constant. In addition, I changed the types to uint8_t to save space, since they are only holding values 0-34, and I put the setup initialization list of pins into an array. I have not compiled this (I am posting from work):

Code:
//Mux control pins (Analog Sensing)
const int E1_Analog = 8;  //A
const int E2_Analog = 7;  //B
const int E3_Analog = 6;  //C
const int E4_Analog = 5;  //D

const int F1_Analog = 4;  //A
const int F2_Analog = 3;  //B
const int F3_Analog = 2;  //C
const int F4_Analog = 1;  //D

// Mux control pins (Digital Controling)
const int G1_Digital = 13;  //A
const int G2_Digital = 14;  //B
const int G3_Digital = 16;  //C
const int G4_Digital = 15;  //D

const int H1_Digital = 9;   //A
const int H2_Digital = 10;  //B
const int H3_Digital = 12;  //C
const int H4_Digital = 11;  //D


// Mux "SIG" pin - The single pin that reads or writes a value to the other 16 pins
const int SIG_pin_Analog_E = A8;
const int SIG_pin_Analog_F = A9;


// Holds the Array of data gathered
// columns are digital and rows are analog reading
const int Grid_Analog_Half = 32;
const int Grid_Digital = 32;

uint8_t pinRowColumn[Grid_Analog_Half][Grid_Digital] = {
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};

// Accelerometer info
const int ypin = A3;                  // y-axis
const int xpin = A4;                  // x-axis

//#define CPU_8MHz       0x01


// List of pins to turn on
static const uint8_t output_pins[] = {
  E1_Analog, E2_Analog, E3_Analog, E4_Analog,
  F1_Analog, F2_Analog, F3_Analog, F4_Analog,
  G1_Analog, G2_Analog, G3_Analog, G4_Analog,
  H1_Analog, H2_Analog, H3_Analog, H4_Analog,
};

void setup(){
  // Setup pins
  for (size_t i = 0; i < sizeof (output_pins) / sizeof (output_pins[0]); i++)
    {
      pinMode (output_pins[i], OUTPUT);
      digitalWrite (output_pins[i], LOW);
    }
    
  Serial.begin(115200);
}

void loop(){ 
  // Turn on each Digital pin individually to measure each analog row
  // e.g. D0 = HIGH, measure all analog. Then D1 = HIGH, measure all analog... etc
  // Scanning
  for (int i = 0; i < Grid_Digital; i++) {  //32
    writeMuxDigital(i);
        
    if ((i % 2) == 1) {
      for (int j = 0; j < Grid_Analog_Half; j++) {  //16
          pinRowColumn[j][i] = readMuxAnalog(j*2); // times 2 so that all even ports are selected.
      }
    }
    else {
        for(int j = 0; j < Grid_Analog_Half; j++) {  //16
            pinRowColumn[j][i] = readMuxAnalog((j*2)+1); // times 2 +1 so that all odd ports are selected.
        }
      }
  }

    // Package BEGIN Check Values
    Serial.print("233 0 233 ");    
      
    // Send one packet of Data over Serial.
    for(int i = 0; i < Grid_Digital; i++) {
      for (int j = 0; j < Grid_Analog_Half; j++) {
        Serial.print(pinRowColumn[j][i]);
        Serial.print(" ");
      } 
    }
    
    // Acclerometer data X & Y
    Serial.print(analogRead(xpin));
    Serial.print(" ");
    Serial.print(analogRead(ypin));
    
    // Package END Check Values
    Serial.println(" 244 0 244");
    
    delay(20);
}


static const uint8_t controlPin_E[] = {E1_Analog, E2_Analog, E3_Analog, E4_Analog};
static const uint8_t controlPin_F[] = {F1_Analog, F2_Analog, F3_Analog, F4_Analog};

static const uint8_t muxChannel[16][4]={
  {LOW, LOW, LOW, LOW}, //channel 0
  {HIGH,LOW, LOW, LOW}, //channel 1
  {LOW, HIGH,LOW, LOW}, //channel 2
  {HIGH,HIGH,LOW, LOW}, //channel 3
  {LOW, LOW, HIGH,LOW}, //channel 4
  {HIGH,LOW, HIGH,LOW}, //channel 5
  {LOW, HIGH,HIGH,LOW}, //channel 6
  {HIGH,HIGH,HIGH,LOW}, //channel 7
  {LOW, LOW, LOW,HIGH}, //channel 8
  {HIGH,LOW, LOW,HIGH}, //channel 9
  {LOW, HIGH,LOW,HIGH}, //channel 10
  {HIGH,HIGH,LOW,HIGH}, //channel 11
  {LOW, LOW,HIGH,HIGH}, //channel 12
  {HIGH,LOW,HIGH,HIGH}, //channel 13
  {LOW,HIGH,HIGH,HIGH}, //channel 14
  {HIGH,HIGH,HIGH,HIGH}  //channel 15
};

int readMuxAnalog(int channel){

  //loop through the 4 SIG pins to program Multiplexer
  for(int i = 0; i < 4; i ++){
    if (channel < (Grid_Analog_Half/2)) {
      digitalWrite(controlPin_E[i], muxChannel[channel][i]);
    }
    else {
      digitalWrite(controlPin_F[i], muxChannel[channel][i]);
    }
  }

  //read the value at the SIG pin
  //return the value
  if (channel < (Grid_Analog_Half/2)) {
      int val = analogRead(SIG_pin_Analog_E);;
      val = val/4; // scales 1024 to 256
      return val;
    }
    else {
      int val = analogRead(SIG_pin_Analog_F);
      val = val/4; // scales 1024 to 256
      return val;
    }
}

static const int controlPin_G[] = {G1_Digital, G2_Digital, G3_Digital, G4_Digital};
static const int controlPin_H[] = {H1_Digital, H2_Digital, H3_Digital, H4_Digital};

static const int muxChannel[16][4]={
  {LOW, LOW, LOW, LOW}, //channel 0
  {HIGH,LOW, LOW, LOW}, //channel 1
  {LOW, HIGH,LOW, LOW}, //channel 2
  {HIGH,HIGH,LOW, LOW}, //channel 3
  {LOW, LOW, HIGH,LOW}, //channel 4
  {HIGH,LOW, HIGH,LOW}, //channel 5
  {LOW, HIGH,HIGH,LOW}, //channel 6
  {HIGH,HIGH,HIGH,LOW}, //channel 7
  {LOW, LOW, LOW,HIGH}, //channel 8
  {HIGH,LOW, LOW,HIGH}, //channel 9
  {LOW, HIGH,LOW,HIGH}, //channel 10
  {HIGH,HIGH,LOW,HIGH}, //channel 11
  {LOW, LOW,HIGH,HIGH}, //channel 12
  {HIGH,LOW,HIGH,HIGH}, //channel 13
  {LOW,HIGH,HIGH,HIGH}, //channel 14
  {HIGH,HIGH,HIGH,HIGH}  //channel 15
};

int writeMuxDigital(int channel){

  //loop through the 4 SIG pins to program Multiplexer
  for(int i = 0; i < 4; i ++){
    if (channel < (Grid_Digital/2)) {
      digitalWrite(controlPin_G[i], muxChannel[channel][i]);
    }
    else {
      digitalWrite(controlPin_H[i], muxChannel[channel][i]);
    }      
  }
}

<edit2>
In looking at it, the definition of the analog pins is wrong if you are doing analogReads on these pins (I haven't looked in detail at which pins you do analogRead on, but I was assuming all of the *_Analog pins need to be setup for Analog). The setup code probably needs to be modified in this case to use INPUT mode and not OUTPUT. If these really are analog pins, you should be using A0..A9 for these pins, not 0..9:

Code:
//Mux control pins (Analog Sensing)
const int E1_Analog = A8;  //A
const int E2_Analog = A7;  //B
const int E3_Analog = A6;  //C
const int E4_Analog = A5;  //D

const int F1_Analog = A4;  //A
const int F2_Analog = A3;  //B
const int F3_Analog = A2;  //C
const int F4_Analog = A1;  //D

<edit3>
And furthermore, the digital pins overlap with the analog pins. A0 is digital pin 14 on the Teensy, A1 is digital pin 15, etc. You will need to rewire your code. As an example, I moved the digital pins to 0..12 (keeping pin 13 as the LED pin):

Code:
// Mux control pins (Digital Controling)
const int G1_Digital = 12;  //A
const int G2_Digital = 11;  //B
const int G3_Digital = 10;  //C
const int G4_Digital = 9;  //D

const int H1_Digital = 8;   //A
const int H2_Digital = 7;  //B
const int H3_Digital = 6;  //C
const int H4_Digital = 5;  //D
 
Last edited:
Hey everyone!

Thanks for your phenomenal help! with some rewriting of my code I managed to get it working! I got to say, as a designer I always enjoy listening to people who have mastered a skill set enough to be able to help someone else.

Anyhow, I figured that if anyone else comes across the same problem.. it would be nice if the code was shared. But before I do, some notes:

- the variables EFGH_Digital and EFGH_Analog, do not represent analog and digital pins. They represent the 4 bit coding pins for the multiplexers, where E/F/G/H all stand for one of the four multiplexers. The terms digital and analog come into play because the common-pins for two multiplexers are digital outputs that blast on/off 5V and the other two are analog inputs that scan.

- Thanks especially for the shifting of variables to global, the variable type changes to char and const. I think this made a large difference!

- I noticed I set one of the multiplexer control pins to pin 1. This is the TX pin, and this link here says that that would kill the Serial. Not sure why it works then?

Code:
//Mux control pins (Analog Sensing)
const int E1_Analog = 8;  //A
const int E2_Analog = 7;  //B
const int E3_Analog = 6;  //C
const int E4_Analog = 5;  //D

const int F1_Analog = 4;  //A
const int F2_Analog = 3;  //B
const int F3_Analog = 2;  //C
const int F4_Analog = 1;  //D

// Mux control pins (Digital Controling)
const int G1_Digital = 13;  //A
const int G2_Digital = 14;  //B
const int G3_Digital = 16;  //C
const int G4_Digital = 15;  //D

const int H1_Digital = 9;   //A
const int H2_Digital = 10;  //B
const int H3_Digital = 12;  //C
const int H4_Digital = 11;  //D

// Mux "SIG" pin - The single pin that reads or writes a value to the other 16 pins
const int SIG_pin_Analog_E = A8;
const int SIG_pin_Analog_F = A9;

// Accelerometer info
const int ypin = A3;                  // y-axis
const int xpin = A4;                  // x-axis

// List of pins to turn on
static const uint8_t output_pins[] = {
  E1_Analog, E2_Analog, E3_Analog, E4_Analog,
  F1_Analog, F2_Analog, F3_Analog, F4_Analog,
  G1_Digital, G2_Digital, G3_Digital, G4_Digital,
  H1_Digital, H2_Digital, H3_Digital, H4_Digital,
};

// Control pin declaring
static const uint8_t controlPin_E[] = {E1_Analog, E2_Analog, E3_Analog, E4_Analog};
static const uint8_t controlPin_F[] = {F1_Analog, F2_Analog, F3_Analog, F4_Analog};
static const uint8_t controlPin_G[] = {G1_Digital, G2_Digital, G3_Digital, G4_Digital};
static const uint8_t controlPin_H[] = {H1_Digital, H2_Digital, H3_Digital, H4_Digital};

// Defining Multiplexers binary code to select pin
int muxChannel[16][4]={
    {LOW, LOW, LOW, LOW}, //channel 0
    {HIGH,LOW, LOW, LOW}, //channel 1
    {LOW, HIGH,LOW, LOW}, //channel 2
    {HIGH,HIGH,LOW, LOW}, //channel 3
    {LOW, LOW, HIGH,LOW}, //channel 4
    {HIGH,LOW, HIGH,LOW}, //channel 5
    {LOW, HIGH,HIGH,LOW}, //channel 6
    {HIGH,HIGH,HIGH,LOW}, //channel 7
    {LOW, LOW, LOW,HIGH}, //channel 8
    {HIGH,LOW, LOW,HIGH}, //channel 9
    {LOW, HIGH,LOW,HIGH}, //channel 10
    {HIGH,HIGH,LOW,HIGH}, //channel 11
    {LOW, LOW,HIGH,HIGH}, //channel 12
    {HIGH,LOW,HIGH,HIGH}, //channel 13
    {LOW,HIGH,HIGH,HIGH}, //channel 14
    {HIGH,HIGH,HIGH,HIGH}  //channel 15
  };


// Holds the Array of data gathered
// columns are digital and rows are analog reading
const int Grid_Analog_Half = 16;
const int Grid_Digital = 32;

unsigned char pinRowColumn[Grid_Analog_Half][Grid_Digital] = {
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};

//#define CPU_8MHz       0x01


void setup(){
  // Setup pins
  for (size_t i = 0; i < sizeof (output_pins) / sizeof (output_pins[0]); i++) {
      pinMode (output_pins[i], OUTPUT);
      digitalWrite (output_pins[i], LOW);
    }
    
  // Start serial port 1
  Serial.begin(115200);
}

void loop(){ 
  // Turn on each Digital pin individually to measure each analog row
  // e.g. D0 = HIGH, measure all analog. Then D1 = HIGH, measure all analog... etc
  // Scanning
  for (int i = 0; i < Grid_Digital; i++) {  //32
    writeMuxDigital(i);
        
    if ((i % 2) == 1) {
      for (int j = 0; j < Grid_Analog_Half; j++) {  //16
          pinRowColumn[j][i] = readMuxAnalog(j*2); // times 2 so that all even ports are selected.
      }
    }
    else {
        for(int j = 0; j < Grid_Analog_Half; j++) {  //16
            pinRowColumn[j][i] = readMuxAnalog((j*2)+1); // times 2 +1 so that all odd ports are selected.
        }
      }
  }

    // Package BEGIN Check Values
    Serial.print("233 0 233 ");    
      
    // Send one packet of Data over Serial.
    for(int i = 0; i < Grid_Digital; i++) {
      for (int j = 0; j < Grid_Analog_Half; j++) {
        Serial.print(pinRowColumn[j][i]);
        Serial.print(" ");
      } 
    }
    
    // Acclerometer data X & Y
    Serial.print(analogRead(xpin));
    Serial.print(" ");
    Serial.print(analogRead(ypin));
    
    // Package END Check Values
    Serial.println(" 244 0 244");
    
    delay(30);
}


int readMuxAnalog(int channel){
  //loop through the 4 SIG pins to program Multiplexer
  for(int i = 0; i < 4; i ++){
    if (channel < (Grid_Analog_Half/2)) {
      digitalWrite(controlPin_E[i], muxChannel[channel][i]);
    }
    else {
      digitalWrite(controlPin_F[i], muxChannel[channel][i]);
    }
  }

  //read the value at the SIG pin
  //return the value
  if (channel < (Grid_Analog_Half/2)) {
      int val = analogRead(SIG_pin_Analog_E);;
      val = val/4; // scales 1024 to 256
      return val;
    }
    else {
      int val = analogRead(SIG_pin_Analog_F);
      val = val/4; // scales 1024 to 256
      return val;
    }
}


int writeMuxDigital(int channel){
  //loop through the 4 SIG pins to program Multiplexer
  for(int i = 0; i < 4; i ++){
    if (channel < (Grid_Digital/2)) {
      digitalWrite(controlPin_G[i], muxChannel[channel][i]);
    }
    else {
      digitalWrite(controlPin_H[i], muxChannel[channel][i]);
    }      
  }
}

Lastly, it needs some more tweaking. The Serial interface with MaxMSP is causing a massive latency and I am still looking for alternative solutions for that. Does anyone know a better way to interface from an Arduino.. to use my grid of sensors as a controller? MIDI, OSC, or some way to encode the array as greyscale pixels and stream it as a video? any ideas are greatly appreciated.
 
Last edited:
On Teensy Serial (over USB) is unrelated to Serial1, Serial2 etc (connected to the relevant pins). (Unlike Arduino which uses a Serial to USB converter).
It seems that OSC is a popular option on Max/MSP, whether it has higher performance than Serial on that platform is worth testing.
 
Status
Not open for further replies.
Back
Top