In this version, we were able to build a working prototype of our Elevate table. The table was able to sense pressure applied to a top panel and activate and LED and the stepper motor, which in turn, raises the panel. See demo video below.

Future improvements will aim to make the pressure sensing more consistent. Currently, we are using a small, circular FSR to detect pressure. To better detect all objects, we would use a large square FSR. Additionally, we would like to improve the quality of the panels by leveling the top of the table.

Code:

Master Arduino:


// Include the Arduino Stepper.h library:
#include <Wire.h&gt;


const int aA                 = 0;
const int aX                 = 1;
const int aY                 = 2;
const int aZ                 = 3;

const int ledA               = 2;
const int ledX               = 3;
const int ledY               = 4;
const int ledZ               = 5;
// Array for LEDs in following order [a,x,y,z]
boolean loaded[4] = {false, false, false, false};

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 40; 


void setup() {
  Serial.begin(9600);
 
  Wire.begin();
  
  
  pinMode(ledA, OUTPUT);
  pinMode(ledX, OUTPUT);
  pinMode(ledY, OUTPUT);
  pinMode(ledZ, OUTPUT);
  
 
}

void loop() {
  hardware_input_poll();
}


void hardware_input_poll(void)
{

  poll_sensor();
 
}


void poll_sensor(){
    // Read the analog input.
    int aVal = analogRead(aA);
    int xVal = analogRead(aX);
    int yVal = analogRead(aY);
    int zVal = analogRead(aZ);

    transmit(aVal, 0);
    transmit(xVal, 1);
    transmit(yVal, 2);
    transmit(zVal, 3);

    poll_lights();
 }

void transmit(int value, int index){
  

   if ( value &gt;= 600 ) {
    if (!loaded[index]){
       
       if  ((millis() - lastDebounceTime) &gt; debounceDelay){
        loaded[index] = true;
        Wire.beginTransmission(4); // transmit to device #4
        Wire.write(index*2);        
        Wire.endTransmission();
      }
      lastDebounceTime = millis();
       
     }

     
      
   } else {
    if (loaded[index]){
      
      if ((millis() - lastDebounceTime) &gt; debounceDelay){
        loaded[index] = false;
        Wire.beginTransmission(4); // transmit to device #4
        Wire.write(index*2+1);        
        Wire.endTransmission();
      }
      lastDebounceTime = millis();
    }
   }
 
}

void poll_lights() {
  if (loaded[0]){
    digitalWrite(ledA, HIGH);
  }else{
    digitalWrite(ledA, LOW);
    }
   if (loaded[1]){
    digitalWrite(ledX, HIGH);
  }else{
    digitalWrite(ledX, LOW);
    }
    if (loaded[2]){
    digitalWrite(ledY, HIGH);
  }else{
    digitalWrite(ledY, LOW);
    }
    if (loaded[3]){
    digitalWrite(ledZ, HIGH);
  }else{
    digitalWrite(ledZ, LOW);
    }
}
 

Stepper Driver Code:

#define enable  8
#define xDir    5
#define yDir    6
#define zDir    7
#define aDir    13
#define xStep   2
#define yStep   3
#define zStep   4
#define aStep   12


#include <Wire.h&gt;


int aPrev = 1;
int xPrev = 3;
int yPrev = 5;
int zPrev = 7;


int steps = 3200;
int stepDelay = 300;


void setup() {
  Serial.begin(9600);
  pinMode(xDir,OUTPUT);
  pinMode(xStep,OUTPUT);  
  pinMode(yDir,OUTPUT);
  pinMode(yStep,OUTPUT); 
  pinMode(zDir,OUTPUT);
  pinMode(zStep,OUTPUT);
  pinMode(aDir,OUTPUT);
  pinMode(aStep,OUTPUT);  
  pinMode(enable,OUTPUT);
  digitalWrite(enable,LOW);

  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent);

}

void loop() {
  delay(100);

}

void step (bool dir, byte dirPin, byte stepperPin, int steps) {
  digitalWrite(dirPin,dir);
  delay(100);
  for (int i = 0; i < steps; i++){
    digitalWrite(stepperPin, HIGH);
    delayMicroseconds(stepDelay);
    digitalWrite(stepperPin, LOW);
    delayMicroseconds(stepDelay);
  }
}

void stepY (bool dir){
  if (dir) {
    step(true,yDir,yStep, 800);
    delay(2000);
  }else {
   step(false, yDir, yStep, 800);
   delay(2000);
  }
   
}

void stepX (bool dir){
  if (dir) {
    step(true,xDir,xStep, 800);
    delay(2000);
  }else {
   step(false, xDir, xStep, 800);
   delay(2000);
  }
   
}

void stepZ (bool dir){
  if (dir) {
    step(true,zDir,zStep, 800);
    delay(2000);
  }else {
   step(false, zDir, zStep, 800);
   delay(2000);
  }
   
}

void stepA (bool dir){
  if (dir) {
    step(true,aDir,aStep, 800);
    delay(2000);
  }else {
   step(false, aDir, aStep, 800);
   delay(2000);
  }
   
}

void receiveEvent(int howMany)
{
  
  int x = Wire.read();
  Serial.println(x);
  
    switch (x) {
      case 0:
        if (aPrev != x) {
          aPrev = x;
          stepA(false);
          break;
        }
      case 1:
        if (aPrev != x) {
          aPrev = x;
          stepA(true);
          break;
        }
      case 2:
        if (xPrev != x) {
          xPrev = x;
          stepX(false);
          break;
        }
      case 3:
        if (xPrev != x) {
          xPrev = x;
          stepX(true);
          break;
        }
      case 4:
        if (yPrev != x) {
          yPrev = x;
          stepY(false);
          break;
        }
      case 5:
        if (yPrev != x) {
          yPrev = x;
          stepY(true);
          break;
        }
      case 6:
        if (zPrev != x) {
          zPrev = x;
          stepZ(false);
          break;
        }
      case 7:
        if (zPrev != x) {
          zPrev = x;
          stepZ(true);
          break;
        }
    }
}