"Lemelson-MIT InvenTeams® are comprised of high school students, educators, and mentors that receive up to $10,000 each to invent technological solutions to real-world problems of their own choosing. STEM educators from the continental U.S., Alaska, Hawaii, and territories of the U.S. may apply."1
This year, we took part in the application phase for MIT's InvenTeam. After brainstorming and researching thoroughly, we came up with several ideas/innovations that would solve problems on the local, national, and world level. We were then able to narrow our invention ideas to three possible inventions. Our class created invention proposals for the three ideas(one per student), after which our teacher, Ms. White, chose one of the three to submit in the InvenTeam application. My invention proposal for a pill bottle lock is above:
Later this year, our team was selected as finalists for the InvenTeam. This selection required another round of application submissions that would be due on September 8, 2020. Although we had already filled out our initial application, the feedback that was provided prompted us to reconsider our idea due to the competition that was already out in the world.
We began our brainstorming with coming up with preexisting problems in various categories in order to come up solutions to the problems. The categories included Local Problems, COVID-19, Bike Theft, Systematic Racism, Random Ideas, and Climate Change.
We finalized our invention proposals by brainstorming a total of three possible inventions for each student. Afterwards, we voted on the ones that did not currently have patents attached to them so that we could use an original idea and make an original invention. An X indicates that a patent for the same or similar idea has already been approved. My final proposals are highlighted above:
We then narrowed down the inventions that had not yet been invented yet and voted on them. They were narrowed down to 4 ideas in the categories of COVID-19, litter, and local problems.
We further narrowed down the remaining ideas into 1 idea. The final idea solved the problem of littering in parks. So, in order to complete the final application for the grant, we chose this idea. The next step involved filling out the application in all of the required areas: Background Research Summary(1), Invention Statement(2), Project Organization and Timeline(3), Planning for Remote Learning and Rapid Closure(4), Budget(5), Community Engagement spreadsheet of Elected Officials and Civic Leaders(6), Team Video and Pictures(7), and Administrative Acceptance Letter of LMIT’s Grant Disbursement Process(8).
The first of the final ideas dealt with the issue of littering in parks. As more people spent time in parks, trash cans' content continued to build up and would only be emptied if a staff member was aware of its status. For a solution, one classmate proposed an automated trash can that would partially be dug into the ground for more space with a hydraulic arm to compress the trash when it surpassed a certain level. If the level was unable to be decreased with the hydraulic arm, a staff member would be notified that the trash can needs to emptied, while also notifying park go-ers that the trash can was full.
During this class period, the bulk of the application, Background Research Summary(1), Invention Statement(2), Project Organization and Timeline(3), Planning for Remote Learning and Rapid Closure(4) were completed in preparation for the deadline next week. I worked with my classmates on part 3 to organize our team roles, and go more in depth with the idea.
Unfortunately, the idea stated above was already in existence, and thus we were left without an idea to continue on with. Going back to the drawing board, we focused on one problem area to create a solution for. We were finally able to expand upon an idea through input from many classmates and the teacher, where we were able to write the application again for this idea.
For privacy reasons, we are unable to publish our idea at this time.(9/13/20)
Police in the United States disproportionately stop, cite, arrest, use force, and kill black men. Our leaders have failed to act to abolish qualified immunity for police officers, and they fail to mandate effective use of police body cameras, making them ineffective sources of data around policing. The number one reason for police interactions with the public is a traffic stop. Our integrated system offers a visual warning to all POs that the exchange will be recorded; it collects evidence about what has occurred while the driver was operating the vehicle, including speed, erratic motion, stops, seat belt use, and phone use that the user can access. As a police officer approaches the vehicle, a recorded warning that the interaction is being recorded and will be available to the public is played. At the same time the driver of the vehicle can begin recording a video that will ultimately be uploaded to a public domain. All police interactions that are recorded will be temporarily stored in a private database and will eventually be published to a public site. The recording will be tied to the police department as well as the badge number of the police officer. Through the crowdsourcing of videos collected by our device, we will increase transparency in police interactions with the community while creating a library of police work that is attached to each police officer. We will protect evidence of interactions in which police officers use force and when deadly force is used, our device will make the public aware immediately when the footage is uploaded to the public domain.
A total of 13 high school InvenTeams were selected as finalists for the 2020 InvenTeam grant to fund the creation of their selected inventions.
Our teacher and our parents worked together to surprise us with the announcement that our application was selected for the grant. The mug to the left was made by a parent and was specialized for each member. We also received a yard sign that stated "A member of the Inventeam lives here."
Tony Perry, a facilitator from the Lemelson-MIT Program, visited our class via zoom to discuss our invention and any planned next steps. He suggested that we zoom out on our invention ideas and not to focus on the specific implementations. It's okay for us as a team to not know how each piece or the invention will be utilized or placed at this point of the design process.
This is a brief overview of the parts we need and functions they will do, taken from the invention statement.
This is a visual representation of the parts and functions made into input and output functions for a better understanding how the whole device will work.
This is a more thorough block diagram than the one above with more detailed input and output functions.
Listed above are the subcategories of the technical team: hardware, data, user interface, and machine learning/AI. Each team has outlined tasks, taken from the invention statement, that will aid in the invention process.
Initial research was conducted to answer a list of driving questions for the hardware subunit of the technical team. The information given includes various arduino-compatible, pre-built systems and alternate hardware options.
We used Flipgrid to record and submit the videos to determine what roles we would hold on the InvenTeam. We all pitched our qualifications for the desired team role and the requirements for the job to ensure that everyone understood what is to be asked of them.
As the research lead, I submitted a research protocol for exemption to the Institutional Review Board(IRB).
These were the initial steps that were compiled to begin working as the hardware team. At the time, our main priority was completing the materials list in order to determine what all needed to be ordered to begin working on the invention.
The site linked above discusses the functionality basics of a NEO-6M GPS module with a Raspberry Pi with the help of the Python software.
The site linked above describes the steps needed to create a live GPS tracker with a GPS module, Raspberry Pi, Python, and Javascript.
The list of materials made in the "initial steps" was made and submitted to our financial lead who then ordered all the necessary materials. Our next step as a team was to familiarize ourselves with the Python software by watching a beginner's guide to the software with various coding exercises. In addition, as the materials arrived, some were tasked with familiarizing themselves with the functionality of the device(s).
I took the above(left) Python course for beginners to familiarize myself with the software that would be used in conjunction with the Raspberry Pi. I went along with the course and copied the provided code through an application named PyCharm. In the above pictures(right), I screenshotted code involving variables and data types, working with numbers, list functions, if statements and comparisons, dictionaries, for loops, comments, classes and objects, building a multiple choice quiz, and inheritance.
The hardware team began to familiarize ourselves with various modules: GPS, accelerometer, camera, audio. The next steps involved our team getting the modules to work and being able to get the data to upload via Bluetooth.
The MPU6050 is a 6-axis accelerometer and gyroscope sensor. It measures temperature, rotational velocity on the X, Y, and Z axis, and gravitational acceleration also on the three axes.
import smbus
import time
class mpu6050:
# Global Variables
GRAVITIY_MS2 = 9.80665
address = None
bus = None
# Scale Modifiers
ACCEL_SCALE_MODIFIER_2G = 16384.0
ACCEL_SCALE_MODIFIER_4G = 8192.0
ACCEL_SCALE_MODIFIER_8G = 4096.0
ACCEL_SCALE_MODIFIER_16G = 2048.0
GYRO_SCALE_MODIFIER_250DEG = 131.0
GYRO_SCALE_MODIFIER_500DEG = 65.5
GYRO_SCALE_MODIFIER_1000DEG = 32.8
GYRO_SCALE_MODIFIER_2000DEG = 16.4
# Pre-defined ranges
ACCEL_RANGE_2G = 0x00
ACCEL_RANGE_4G = 0x08
ACCEL_RANGE_8G = 0x10
ACCEL_RANGE_16G = 0x18
GYRO_RANGE_250DEG = 0x00
GYRO_RANGE_500DEG = 0x08
GYRO_RANGE_1000DEG = 0x10
GYRO_RANGE_2000DEG = 0x18
# MPU-6050 Registers
PWR_MGMT_1 = 0x6B
PWR_MGMT_2 = 0x6C
ACCEL_XOUT0 = 0x3B
ACCEL_YOUT0 = 0x3D
ACCEL_ZOUT0 = 0x3F
TEMP_OUT0 = 0x41
GYRO_XOUT0 = 0x43
GYRO_YOUT0 = 0x45
GYRO_ZOUT0 = 0x47
ACCEL_CONFIG = 0x1C
GYRO_CONFIG = 0x1B
def __init__(self, address, bus=1):
self.address = address
self.bus = smbus.SMBus(bus)
# Wake up the MPU-6050 since it starts in sleep mode
self.bus.write_byte_data(self.address, self.PWR_MGMT_1, 0x00)
# I2C communication methods
def read_i2c_word(self, register):
# Read the data from the registers
high = self.bus.read_byte_data(self.address, register)
low = self.bus.read_byte_data(self.address, register + 1)
value = (high << 8) + low
if (value >= 0x8000):
return -((65535 - value) + 1)
else:
return value
def set_accel_range(self, accel_range):
# First change it to 0x00 to make sure we write the correct value later
self.bus.write_byte_data(self.address, self.ACCEL_CONFIG, 0x00)
# Write the new range to the ACCEL_CONFIG register
self.bus.write_byte_data(self.address, self.ACCEL_CONFIG, accel_range)
def read_accel_range(self, raw = False):
raw_data = self.bus.read_byte_data(self.address, self.ACCEL_CONFIG)
if raw is True:
return raw_data
elif raw is False:
if raw_data == self.ACCEL_RANGE_2G:
return 2
elif raw_data == self.ACCEL_RANGE_4G:
return 4
elif raw_data == self.ACCEL_RANGE_8G:
return 8
elif raw_data == self.ACCEL_RANGE_16G:
return 16
else:
return -1
def get_accel_data(self, g = False):
x = self.read_i2c_word(self.ACCEL_XOUT0)
y = self.read_i2c_word(self.ACCEL_YOUT0)
z = self.read_i2c_word(self.ACCEL_ZOUT0)
accel_scale_modifier = None
accel_range = self.read_accel_range(True)
if accel_range == self.ACCEL_RANGE_2G:
accel_scale_modifier = self.ACCEL_SCALE_MODIFIER_2G
elif accel_range == self.ACCEL_RANGE_4G:
accel_scale_modifier = self.ACCEL_SCALE_MODIFIER_4G
elif accel_range == self.ACCEL_RANGE_8G:
accel_scale_modifier = self.ACCEL_SCALE_MODIFIER_8G
elif accel_range == self.ACCEL_RANGE_16G:
accel_scale_modifier = self.ACCEL_SCALE_MODIFIER_16G
else:
print("Unknown range-accel_scale_modifier set to self.ACCEL_SCALE_MODIFIER_2G")
accel_scale_modifier = self.ACCEL_SCALE_MODIFIER_2G
x = x / accel_scale_modifier
y = y / accel_scale_modifier
z = z / accel_scale_modifier
if g is True:
return {'x': x, 'y': y, 'z': z}
elif g is False:
x = x * self.GRAVITIY_MS2
y = y * self.GRAVITIY_MS2
z = z * self.GRAVITIY_MS2
return {'x': x, 'y': y, 'z': z}
def set_gyro_range(self, gyro_range):
# First change it to 0x00 to make sure we write the correct value later
self.bus.write_byte_data(self.address, self.GYRO_CONFIG, 0x00)
# Write the new range to the ACCEL_CONFIG register
self.bus.write_byte_data(self.address, self.GYRO_CONFIG, gyro_range)
def read_gyro_range(self, raw = False):
raw_data = self.bus.read_byte_data(self.address, self.GYRO_CONFIG)
if raw is True:
return raw_data
elif raw is False:
if raw_data == self.GYRO_RANGE_250DEG:
return 250
elif raw_data == self.GYRO_RANGE_500DEG:
return 500
elif raw_data == self.GYRO_RANGE_1000DEG:
return 1000
elif raw_data == self.GYRO_RANGE_2000DEG:
return 2000
else:
return -1
def get_gyro_data(self):
x = self.read_i2c_word(self.GYRO_XOUT0)
y = self.read_i2c_word(self.GYRO_YOUT0)
z = self.read_i2c_word(self.GYRO_ZOUT0)
gyro_scale_modifier = None
gyro_range = self.read_gyro_range(True)
if gyro_range == self.GYRO_RANGE_250DEG:
gyro_scale_modifier = self.GYRO_SCALE_MODIFIER_250DEG
elif gyro_range == self.GYRO_RANGE_500DEG:
gyro_scale_modifier = self.GYRO_SCALE_MODIFIER_500DEG
elif gyro_range == self.GYRO_RANGE_1000DEG:
gyro_scale_modifier = self.GYRO_SCALE_MODIFIER_1000DEG
elif gyro_range == self.GYRO_RANGE_2000DEG:
gyro_scale_modifier = self.GYRO_SCALE_MODIFIER_2000DEG
else:
gyro_scale_modifier = self.GYRO_SCALE_MODIFIER_250DEG
x = x / gyro_scale_modifier
y = y / gyro_scale_modifier
z = self.read_i2c_word(self.GYRO_ZOUT0)
gyro_scale_modifier = None
gyro_range = self.read_gyro_range(True)
if gyro_range == self.GYRO_RANGE_250DEG:
gyro_scale_modifier = self.GYRO_SCALE_MODIFIER_250DEG
elif gyro_range == self.GYRO_RANGE_500DEG:
gyro_scale_modifier = self.GYRO_SCALE_MODIFIER_500DEG
elif gyro_range == self.GYRO_RANGE_1000DEG:
gyro_scale_modifier = self.GYRO_SCALE_MODIFIER_1000DEG
elif gyro_range == self.GYRO_RANGE_2000DEG:
gyro_scale_modifier = self.GYRO_SCALE_MODIFIER_2000DEG
else:
gyro_scale_modifier = self.GYRO_SCALE_MODIFIER_250DEG
x = x / gyro_scale_modifier
y = y / gyro_scale_modifier
z = z / gyro_scale_modifier
return {'x': x, 'y': y, 'z': z}
def get_all_data(self):
temp = self.get_temp()
accel = self.get_accel_data()
gyro = self.get_gyro_data()
return [accel, gyro, temp]
mpu = mpu6050(0x68)
if __name__ == "__main__":
while (1):
try:
accel_data = mpu.get_accel_data()
gyro_data = mpu.get_gyro_data()
print("Ax:{:.4f}\tAy:{:.4f}\tAz:{:.4f}\tGx:{:.4f}\tGy:{:.4f}\tGz:{:.4f} ".format(accel_data['x'], accel_data['y'], accel_data['z'], gyro_data['x'], gyro_data['y'], gyro_data['z']))
except KeyboardInterrupt:
break
time.sleep(0.5)
I attempted to convert the accelerometer and gyroscope data to a csv file through multiple failed attempts. Due to my lack of understanding of Python, it became difficult for me to troubleshoot what was going wrong. I've decided to switch to using the Sense HAT for the time being.
I decided to start working with the Sense HAT sensor because while it has accelerometer and gyroscope capabilities(in addition to many others), there were resources on how to save the given sensor data as a csv file. This is important because if I am unable to convert the sensor data into a readable file, it cannot be transferred to another device via Bluetooth, which was my goal. The provided site that I used for the Sense HAT has information on saving data as a csv file so I will be attempting to use that information to see if I can do the same with the mpu6050.
I was eventually able to get the sensor readings from the Sense HAT to open and record the data into a csv file. Through this, I am then able to transfer that file to another device, which accomplishes my December goal. I am going to work with the mpu6050 to see if I can also get it to write the data to a file. If I am successful, I will then work on a 3d model that will aid in determining erratic driving. If not, I will continue with the Sense HAT.
from csv import writer
from sense_hat import SenseHat
from datetime import datetime
sense = SenseHat()
def get_sense_data():
sense_data = []
orientation = sense.get_orientation()
orientation["yaw"]
orientation["pitch"]
orientation["roll"]
acc = sense.get_accelerometer_raw()
acc["x"]
acc["y"]
acc["z"]
gyro = sense.get_gyroscope_raw()
gyro["x"]
gyro["y"]
gyro["z"]
datetime.now()
return sense_data
def get_sense_data():
sense_data = []
orientation = sense.get_orientation()
sense_data.append(orientation["yaw"])
sense_data.append(orientation["pitch"])
sense_data.append(orientation["roll"])
acc = sense.get_accelerometer_raw()
sense_data.append(acc["x"])
sense_data.append(acc["y"])
sense_data.append(acc["x"])
gyro = sense.get_gyroscope_raw()
sense_data.append(gyro["x"])
sense_data.append(gyro["y"])
sense_data.append(gyro["z"])
sense_data.append(datetime.now())
return sense_data
with open('data.csv', 'w', newline='') as f:
data_writer = writer(f)
data_writer.writerow(['yaw', 'pitch', 'roll', 'acc_x', 'acc_y', 'acc_z', 'gyro_x', 'gyro_y', 'gyro_z', 'datetime'])
while True:
print(get_sense_data())
data = get_sense_data()
data_writer.writerow(data)
To make it easier to shutdown my raspberry pi, I created code that will shutdown the system, also printing "Shutting Down", when the joystick is pressed for 3 seconds.
from sense_hat import SenseHat
import time
from time import sleep
import os
sense = SenseHat()
event = sense.stick.wait_for_event()
while True:
for event in sense.stick.get_events():
time.sleep(3)
print('Shutting down now')
for event in sense.stick.get_events():
os.system("shutdown now -h")
time.sleep(1)
As part of our path to get the recorded sensor/video/audio to the user, the files needed to be uploaded to the data team, which manages the AWS(amazon web service) buckets. Essentially, the code takes the necessary sensor data, writes it to a csv file, and that file is subsequently uploaded to AWS through the use of a secret access key id and access key.
from sense_hat import SenseHat
from csv import writer
from sense_hat import SenseHat
from datetime import datetime
from Secret import access_key, secret_access_key
#from .boto3 import boto3
import boto3
import os
sense = SenseHat()
client = boto3.client("s3", aws_access_key_id = access_key, aws_secret_access_key = secret_access_key)
def get_sense_data():
sense_data = []
orientation = sense.get_orientation()
orientation["yaw"]
orientation["pitch"]
orientation["roll"]
acc = sense.get_accelerometer_raw()
acc["x"]
acc["y"]
acc["z"]
gyro = sense.get_gyroscope_raw()
gyro["x"]
gyro["y"]
gyro["z"]
datetime.now()
return sense_data
def get_sense_data():
sense_data = []
orientation = sense.get_orientation()
sense_data.append(orientation["yaw"])
sense_data.append(orientation["pitch"])
sense_data.append(orientation["roll"])
acc = sense.get_accelerometer_raw()
sense_data.append(acc["x"])
sense_data.append(acc["y"])
sense_data.append(acc["x"])
gyro = sense.get_gyroscope_raw()
sense_data.append(gyro["x"])
sense_data.append(gyro["y"])
sense_data.append(gyro["z"])
sense_data.append(datetime.now())
return sense_data
with open('CHcombined.csv', 'w', newline='') as f:
data_writer = writer(f)
data_writer.writerow(['yaw', 'pitch', 'roll', 'acc_x', 'acc_y', 'acc_z', 'gyro_x', 'gyro_y', 'gyro_z', 'datetime'])
while True:
print(get_sense_data())
data = get_sense_data()
data_writer.writerow(data)
for file in os.listdir('/home/pi/.local/lib/python2.7/site-packages/'):
if '.csv' in file:
upload_file_bucket = 'mswhitetestdata'
upload_file_key = "python/" +str(file)
client.upload_file(file, upload_file_bucket, upload_file_key)
To make data collection easier, the raspberrypi was coded to begin running code once it has finished booting up, as indicated with the red light. With a push of the button, the light turns green, indicating that the data collection code is running. Pushing the button a second time ends the script and turns off the light.
The presentation detailed all that the team has been able to accomplish towards our device as of February.
This slides presentation documented all of my work towards achieving the goal of getting my accelerometer to run, collect, data, and upload it to Amazon Web Service(AWS). After achieving smaller goals, I was steadily making progress towards my overall goal. Complete documentation was recorded so that if an once-encountered error were to occur, documentation would be available to assist in correcting the error. This came in handy in the later stages of the project as it was necessary for me to flash a new SD card and copy previous code onto it. Following the steps from the ongoing slides allowed for a smooth transition into the use of a new SD card.
This is the final presentation, presented at EurekaFest, for our device. We stopped working on the invention as of May 2021.
September of 2021, the engineering class applied for the Lemelson-MIT InvenTeam Grant, a grant that would supply money to students in their goal to create an invention that will make a lasting impact. Although we went through multiple invention ideas, from solving local and personal problems, our decision to follow through with an invention that aimed to solve part of a ongoing national issue, allowed for our team to experience a student-led invention process that could become the catalyst for future endeavors.
This project provided me with various challenges, some of which I had difficulty overcoming. To begin, our decision to use Python as our coding language was challenging. For the previous two years in engineering, we have used Arduino software, a coding language that I have become familiar with. However, with the shift to Python, I've had to learn a new coding language and input that wasn't needed for Arduino. In the beginning of the invention process, the team was tasked with watching a Python introductory video so we could work on coding. It introduced us to the types of coding and as a result, we began working on our own code, from scratch. Thankfully after a review session with the other InvenTeams, we realized that it was not necessary to write every piece of code from scratch; there were websites with previously-written code dedicated to doing that. This made progress come much more easily, but when encountering errors, we had difficulty determining the issue. Also, as the research lead of the team, there was a lot of stress with the submission of the research protocol for exemption. This was a process that I was unfamiliar with, a process that would cause more money to be used from the grant if I failed to produce an adequate protocol. If the research protocol was rejected, money that could have been used towards the physical parts of the invention would have to be spent towards fixing the protocol. This realization only added to my high level of stress.
With the numerous challenges came numerous instances of success. Throughout my time working with Python, I slowly became more familiar with the language, and the solutions to errors I encountered. Instead of viewing the errors as a complete failure, I viewed them as mistakes that caused minor setbacks for my goals that I could overcome with time. During this point, the raspberrypi forums became my best friend. I was able to search produced errors and was able to find sites that addressed the issue and provided solutions. In addition, as part of the hardware team, our goals frequently aligned with each other, and so, we were were able to assist different members with tasks that had previously been accomplished by another.
My assumption of the invention process from prior years of engineering was unlike the process that I went through for this invention. We unknowingly went through the engineering design process during the invention process. Unlike engineering class, we did not identify what stages we were at throughout the process, but rather went through the same steps in the same order without realizing. This project has taught me to not expect the same experience when undergoing the engineering design process because it is different for every project.
As part of the hardware team, I've become more accustomed to and familiar with coding language. Although it has and will continue to aid me in the engineering field, my goal of becoming an environmental engineer has not changed. I don't know what the environmental engineering path will entail but if it requires me to use my knowledge on computer coding language, this experience would have aided me greatly.