diff --git a/Input Devices 2022.pdf b/Input Devices 2022.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..99763cbee53e2e31f8ab469d6298f25161463bfb
Binary files /dev/null and b/Input Devices 2022.pdf differ
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..51d9195cc51f23f183db54f6663f15f6a7d982bc
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+# Input Devices Recitation
+
+This recitation aims to introduce the basics of working with inputs on Arduino embeded devices. Slides are hosted [here](https://gitlab.cba.mit.edu/classes/863.22/site/-/blob/master/doc/input_devices/Input%20Devices%202022.pdf).
+
+### Example Code
+
+1) [inputDevices_1_basic.ino](https://gitlab.cba.mit.edu/classes/863.22/site/-/blob/master/doc/input_devices/inputDevices_1_basic.ino) is a simple sketch introducing analogRead().
+
+2) [inputDevices_2_gauss.ino](https://gitlab.cba.mit.edu/classes/863.22/site/-/blob/master/doc/input_devices/inputDevices_1_basic.ino) adds a tare, ADC resolution, and conversion to Gauss.
+
+3) [inputDevices_3_filters.ino](https://gitlab.cba.mit.edu/classes/863.22/site/-/blob/master/doc/input_devices/inputDevices_1_basic.ino) shows various filtering approaches, including batch averaging, moving averaging, and low pass filters.
+
+4) [inputDevices_4_linearization.ino](https://gitlab.cba.mit.edu/classes/863.22/site/-/blob/master/doc/input_devices/inputDevices_1_basic.ino) shows a simple lookup table implementation with linearization.
diff --git a/inputDevices_2_gauss.ino b/inputDevices_2_gauss.ino
new file mode 100644
index 0000000000000000000000000000000000000000..7024489eabdc009bca642e39d76eaac7cf0ce721
--- /dev/null
+++ b/inputDevices_2_gauss.ino
@@ -0,0 +1,20 @@
+// Variables
+const int sensorPin = 27;
+float reading = 0;
+float tare = 0;                                            // initializing our tare
+const int ADC_res = 10;                                    // desired ADC resolution
+const float sens = 0.005;                                  // V/G, taken from datasheet
+const float conversion_factor = 3.3/(pow(2,ADC_res))/sens; // [V/ADC] / [V/G] gives us Gauss/ADC
+
+void setup() {
+    Serial.begin(115200);
+    analogReadResolution(ADC_res);                         // Here we can set the number of bits used by our ADC 
+    tare = analogRead(sensorPin);                          // Take one reading to use as our tare value
+}
+
+void loop() {
+    float reading = (analogRead(sensorPin) - tare)*conversion_factor; // now we will subtract by our tare, and multiply by our conversion factor
+    Serial.print(reading);
+    Serial.println(" Gauss");
+    delay(10);
+}
diff --git a/inputDevices_3_filters.ino b/inputDevices_3_filters.ino
new file mode 100644
index 0000000000000000000000000000000000000000..32ef0f95be99668faff69865385b977f934e2203
--- /dev/null
+++ b/inputDevices_3_filters.ino
@@ -0,0 +1,67 @@
+// Variables
+  const int sensorPin = 27;
+  float reading = 0;
+  float tare = 0;
+
+// Variables for Averaging
+  const int totalSamples = 10;
+  int index_avg = 0;
+  int value = 0;
+  float sum = 0;
+  int readings[totalSamples]; // create an empty array of size totalSamples
+
+// Variables for Low Pass
+  float filteredOutputPrevious = 0;
+  const float RC = 0.159;
+  const float dT = 0.01; // time in seconds
+  const float C1 = dT/(RC+dT); // coefficient 1
+  const float C2 = RC/(RC+dT); // coefficient 2
+
+void setup() {
+    Serial.begin(115200);                                     // initialize serial communication with computer:
+    analogReadResolution(10);                               // Here we can set the number of bits used by our ADC 
+    
+   // Now for our tare, we can use our low pass filter several times to get more accuracy
+    filteredOutputPrevious = analogRead(sensorPin);         // First let's initialize the previous value with a single new reading
+    for (int i = 0; i < 10; i++) {                          // Next let's repeat the measurement a few times to make sure we are getting a nice filtered output
+        tare = lowPassRead();
+    }
+}
+
+void loop() {
+    float reading = analogRead(sensorPin)  - tare;
+    Serial.print(reading);
+    Serial.print(", ");
+    float filtered_reading = batchAverageRead() - tare;             // Batch average reading
+    //float filtered_reading = movingAverageRead()  - tare;           // Moving average read
+    //float filtered_reading = lowPassRead()  - tare;                   // Low pass read
+    Serial.println(filtered_reading);                                 // send our reading over USB to the computer
+    delay(dT*1000);                                                   // delay between reads in miliseconds (necessary for low pass)
+}
+
+// Batch Averaged sensor reading ----------------------------------------------------
+float batchAverageRead(){
+    sum = 0;
+    for (int i = 0; i < totalSamples; i++){
+        sum = sum + analogRead(sensorPin);                            // sum totalSamples readings
+        delay(dT*1000);                                                    // wait for every reading! This is bad :(
+    }
+    return sum / totalSamples;
+}
+
+// Moving Average sensor reading ----------------------------------------------------
+float movingAverageRead(){
+    sum = sum - readings[index_avg];                            // Remove the oldest entry from the sum
+    value = analogRead(sensorPin);                              // Read the next sensor value
+    readings[index_avg] = value;                                // Add the newest reading to the window
+    sum = sum + value;                                          // Add the newest reading to the sum
+    index_avg = (index_avg+1)%totalSamples;                     // Increment the index, and wrap to 0 if it exceeds the window size
+    return sum/(float(totalSamples));                           // Divide the sum of the window by the window size for the result
+}
+
+// Low Pass Filter sensor reading -------------------------------------------------
+float lowPassRead(){
+    float filteredOutput = analogRead(sensorPin)*(C1) + filteredOutputPrevious*(C2);  // All we need to do here is to measure once and do some fast multiplication with our coefficients! This is great :)
+    filteredOutputPrevious = filteredOutput;                                          // And store our output for next time
+    return filteredOutput;
+}
diff --git a/inputDevices_4_linearization.ino b/inputDevices_4_linearization.ino
new file mode 100644
index 0000000000000000000000000000000000000000..a8f7b8e614c8a1da605c5aebda390530272dec63
--- /dev/null
+++ b/inputDevices_4_linearization.ino
@@ -0,0 +1,61 @@
+// Variables
+const int sensorPin = 27;
+float reading = 0;
+float tare = 0;
+
+// Variables for Low Pass
+float filteredOutputPrevious = 0;
+const float RC = 0.159;
+const float dT = 0.01; // time in seconds
+const float C1 = dT/(RC+dT); // coefficient 1
+const float C2 = RC/(RC+dT); // coefficient 2
+
+// Variables for linearization 
+const int interp_samples = 10;
+float interp_inputs[interp_samples]  = {296, 200.3, 139.5, 100.8, 75, 57, 44.05, 35, 28, 23};   // Raw ADC readings
+float interp_outputs[interp_samples] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18};                     // Associated linear distances
+
+void setup() {
+    Serial.begin(115200);                                     // Initialize serial communication with computer:
+   // Now for our tare, we can use our low pass filter several times to get more accuracy
+    filteredOutputPrevious = analogRead(sensorPin);         // First let's initialize the previous value with a single new reading
+    for (int i = 0; i < 10; i++) {                          // Next let's repeat the measurement a few times to make sure we are getting a nice filtered output
+        tare = lowPassRead();
+    }
+}
+
+void loop() {
+    float filtered_reading = lowPassRead()  - tare;         // we will always subtract the tare from our readings
+    linearized(filtered_reading);                           // send our reading over USB to the computer
+    delay(dT*1000);                                         // delay between reads in miliseconds
+}
+
+// Low Pass Filter sensor reading -------------------------------------------------
+float lowPassRead(){
+    float filteredOutput = analogRead(sensorPin)*(C1) + filteredOutputPrevious*(C2);
+    filteredOutputPrevious = filteredOutput;
+    return filteredOutput;
+}
+
+// Linearization ------------------------------------------------------------------
+float linearized(float reading){
+    float linear_output = reading;                                                                                  // Print our raw output for reference first
+    Serial.print("Raw reading: ");
+    Serial.print(reading);
+    if (reading <= interp_inputs[0] && reading >= interp_inputs[interp_samples-1]){                                 // If we are reading within the interpolation lookup range
+        for (int i = 0; i <= interp_samples; i++){
+            if (reading > interp_inputs[i]){                                                                        // Find our exact location by iterating through the table and checking each time
+                float scaling_factor = abs((reading - interp_inputs[i]) / (interp_inputs[i] - interp_inputs[i-1])); // Calculate our percentage between two interpolation points
+                linear_output = (interp_outputs[i-1] - interp_outputs[i])*scaling_factor + interp_outputs[i];       // Apply that scaling factor to the associated conversion points
+                Serial.print(" Linearized reading: ");
+                Serial.print(linear_output);
+                Serial.println(" mm");
+                break;
+            }
+        }
+    }
+    else {
+        Serial.println(" Outside of interpolation range");
+    }
+    return linear_output;
+}