Difference between revisions of "Library Chair"
m (Protected "Library Chair" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))) |
|||
(80 intermediate revisions by 3 users not shown) | |||
Line 2: | Line 2: | ||
It's a Wednesday night. You're sitting in your room watching Netflix, putting off studying for your exam next week. You're cozy in bed, and it's cold and dark outside, plus your suite-mate just said he's ordering Domino's and there might be a slice or two left over for you. Every fiber of your being is willing you to stay home, eat, and watch TV, but that nagging voice in the back of your head tells you that you're a Wash U student damnit, and you'd better take this exam seriously! So you muster up some energy and get the kid on your floor who is in the class with you to walk to the library and study for a bit. When you guys get there, though, you see that every seat in the library is taken! ARGH!! | It's a Wednesday night. You're sitting in your room watching Netflix, putting off studying for your exam next week. You're cozy in bed, and it's cold and dark outside, plus your suite-mate just said he's ordering Domino's and there might be a slice or two left over for you. Every fiber of your being is willing you to stay home, eat, and watch TV, but that nagging voice in the back of your head tells you that you're a Wash U student damnit, and you'd better take this exam seriously! So you muster up some energy and get the kid on your floor who is in the class with you to walk to the library and study for a bit. When you guys get there, though, you see that every seat in the library is taken! ARGH!! | ||
− | Few things are more annoying than when you decide to actually go study but then can't because there isn't an open spot for you in the library. Enter the '''Library Chair'''. In simple terms the '''Library Chair''' system consists of an interactive chair and a web interface. The chair can detect when someone is sitting in it, and this information is then relayed (via a few | + | Few things are more annoying than when you decide to actually go study but then can't because there isn't an open spot for you in the library. Enter the '''Library Chair'''. In simple terms the '''Library Chair''' system consists of an interactive chair and a web interface. The chair can detect when someone is sitting in it, and this information is then relayed (via a few Arduinos and a Raspberry Pi) to a website which displays a map of all the chairs in the library and which ones are occupied. You can check this website from the safety and comfort of your own room; no more cold walks to the library that end up being futile! |
For more specific information on how the system operates, please look at the "Design and Solutions" section of this wiki. | For more specific information on how the system operates, please look at the "Design and Solutions" section of this wiki. | ||
Line 18: | Line 18: | ||
==Objectives== | ==Objectives== | ||
− | Our group's main objective | + | Our group's main objective was to create an interface that library goers could use to see which seats in the library are available, and which are occupied. This interface is dependent on voltage data obtained from a circuit hooked up to an Arduino and affixed to the bottom of a library chair. When a human body moves close to the circuit, i.e when someone sits down in the chair, the output voltage changes and chair occupancy can thus be determined. This circuit then communicates occupancy and location data to another Arduino connected to a Raspberry Pi. The Raspberry Pi will in turn communicate this data to a web server. We aim for the circuit/Arduino device to be accurate, low energy, and powered by solar panels. |
− | As individuals we are simultaneously working on a few different smaller goals. These include: finalizing the circuit that will detect when someone is sitting in the chair, figuring out how to communicate effectively between the | + | As individuals we are simultaneously working on a few different smaller goals. These include: finalizing the circuit that will detect when someone is sitting in the chair, figuring out how to communicate effectively between the Arduinos and how to generate the wave function necessary for the circuit to operate from an Arduino, integrating a solar power source into the circuit, communicating data from the Raspberry Pi to a web server, and designing and implementing an aesthetically pleasing web interface. |
==Challenges== | ==Challenges== | ||
− | *Learning how to use the TI microcontrollers. This proved to be too difficult, so we adapted and used | + | *Learning how to use the TI microcontrollers. This proved to be too difficult, so we adapted and used Arduinos instead. |
*Rebuilding the circuit after someone burned it in the lab | *Rebuilding the circuit after someone burned it in the lab | ||
*Getting accurate current and voltage readings from solar panels/batteries | *Getting accurate current and voltage readings from solar panels/batteries | ||
− | *Needing to find a new ADC solution after realizing the built in | + | *Needing to find a new ADC solution after realizing the built in Arduino ADC was not powerful enough |
+ | * Creating a simple button program to get our web page to react to a button pushed from the Pi | ||
+ | * Trial and error with making website dynamic (attempting with PHP, trying HTML-code-writing code, creating text files and uploading them as input, and finally using an online database) | ||
==Gantt Chart== | ==Gantt Chart== | ||
Line 83: | Line 85: | ||
After prototyping on the NI Elvis, we determined that the best form of input voltage to the circuit would be a 5V square wave with a frequency of around 800kHz and a duty cycle of 50%. (For help prototyping on an NI Elvis board see our tutorial https://classes.engineering.wustl.edu/ese205/core/index.php?title=Use_a_NI_Elvis_board). Since a square wave is always either ‘on’ or ‘off’, this input means that the capacitor is always either charging or discharging, which lets us get more consistent output voltage readings from the circuit. We determined the optimal frequency through trial and error and striking a balance between signal magnitude and signal noise: using a higher input frequency led to a noisier output voltage signal, but using a lower frequency led to less of a change in voltage. | After prototyping on the NI Elvis, we determined that the best form of input voltage to the circuit would be a 5V square wave with a frequency of around 800kHz and a duty cycle of 50%. (For help prototyping on an NI Elvis board see our tutorial https://classes.engineering.wustl.edu/ese205/core/index.php?title=Use_a_NI_Elvis_board). Since a square wave is always either ‘on’ or ‘off’, this input means that the capacitor is always either charging or discharging, which lets us get more consistent output voltage readings from the circuit. We determined the optimal frequency through trial and error and striking a balance between signal magnitude and signal noise: using a higher input frequency led to a noisier output voltage signal, but using a lower frequency led to less of a change in voltage. | ||
− | 800kHz is an extremely high frequency, though, considering that the | + | 800kHz is an extremely high frequency, though, considering that the Arduino Uno CPU has a clock speed of 16MHz, so we searched for a library that could be of use and found this: https://forum.arduino.cc/index.php?topic=117425.0 . However, we struggled to implement it correctly, and further testing showed that we would only need a frequency of around 50-70 kHz. |
− | We used pulse width modulation on the | + | We used pulse width modulation on the Arduino's digital pin number 6 (as seen in Figure 1.1) to supply this square wave. The default frequency for pulse width modulation on digital pin 6 is 976.56 Hz, and the default voltage is 5V. In order to increase this frequency, we reduced the PWM prescaler value on the TCCR0B timer register to 1 from a default of 64, thereby increasing the frequency by a factor of 64. (For reference see: https://arduino-info.wikispaces.com/Arduino-PWM-Frequency) |
Here is the code we used to generate the 5V 63kHz square wave input: | Here is the code we used to generate the 5V 63kHz square wave input: | ||
Line 95: | Line 97: | ||
void loop() {<br /> | void loop() {<br /> | ||
− | analogWrite(6,128); //sets up square | + | analogWrite(6,128); //sets up square wave with duty=50%<br /> |
}<br /> | }<br /> | ||
==== 1.3 Measure voltage flow exiting circuit, and analyze to determine occupancy ==== | ==== 1.3 Measure voltage flow exiting circuit, and analyze to determine occupancy ==== | ||
− | We initially tried to use the | + | We initially tried to use the Arduino's built in 10-bit analog-to-digital converter (ADC) to detect changes in output voltage from the circuit. Using the minimum reference voltage of 1.1V and 1023 'steps' of specificity (2^10 = 1024), gave us a step size of ~1mV. Since we were dealing with changes in voltage (voltage when chair is occupied vs voltage when chair is vacant) on the order of ''micro''volts, we needed another solution. We found a compatible 16-bit external ADC (https://www.adafruit.com/product/1085) and wired it up as shown in Figure 1.2. This converter has about 65,000 'steps' of specificity (2^16~65000), enabling detection of voltage changes as small as 0.0002V. We wired in a differential connection to the external converter, which is more favorable than a single-ended connection when trying to reduce noise. In order to accurately interpret this very noisy data, we had to implement a multi-tiered rolling average filter to smooth the data. The exact voltage cutoff values signifying either occupancy or vacancy are dependent on the composition and the environment of the chair, and as such need to be tested for and updated whenever the circuit is affixed to a new chair or the chair is moved. |
The code to read in voltages using the external converter and then determine vacancy/occupancy using multi-tiered filters can be found here: | The code to read in voltages using the external converter and then determine vacancy/occupancy using multi-tiered filters can be found here: | ||
Line 110: | Line 112: | ||
''<small>Figure 1.2 - The external 16-bit analog-to-digital converter used to take voltage readings from the circuit</small>'' | ''<small>Figure 1.2 - The external 16-bit analog-to-digital converter used to take voltage readings from the circuit</small>'' | ||
− | ==== 1.4 Integrate | + | ==== 1.4 Integrate Arduino and circuit and attach to chair ==== |
+ | |||
+ | We used a solderless breadboard to connect the Arduino to the RC circuit, the external ADC converter, and an RF transmitter. We made these connections as shown in Figure 1.1, Figure 1.2, and Figure 2.1. The circuit/Arduino system is shown in Figure 1.3. In order to improve the aesthetics of the system, we designed and 3D printed a case (Figure 1.4) to cover up all the wires and circuitry. We then screwed this case to the underside of the chair, and put the metal plate from the RC circuit inside the stuffing of the chair in order to get readings most effectively. | ||
+ | |||
+ | |||
+ | [[File:exhibita.jpeg|frameless|The circuit/Arduino system]] | ||
+ | |||
+ | [[File:CircuitArduinoCase.JPG|frameless|A rendering of the case for the Arduino and circuit.]] | ||
+ | |||
+ | [https://www.thingiverse.com/thing:2704659 Link to Thingiverse with Case CAD files] | ||
+ | |||
+ | ''<small>Figure 1.3 The circuit/Arduino system. Figure 1.4: A rendering of the case for the Arduino and circuit.</small>'' | ||
+ | |||
+ | ==== 1.5 Power the Arduino/circuit with solar power and batteries ==== | ||
+ | In order to power the Arduino our plan was to use a system of batteries and solar panels. The batteries are the main source of power to the Arduino and the solar panels recharge the batteries. | ||
+ | |||
+ | We ended up using 6 1.2V 2400mAh batteries (https://www.amazon.com/gp/product/B00HZV9TGS/ref=oh_aui_detailpage_o02_s00?ie=UTF8&psc=1), wired in series to create a 7.2V 2400mAh system (the recommended input voltage for the Arduino uno is 7V-12V). We also connected 7 680 Ohm resistors wired in parallel to avoid overheating and to regulate the supply of current to the Arduino. When testing with the NI Elvis and an ammeter the system was drawing around 70mA of current but according to information from various datasheets, we had estimated that powering the ADC converter, the RF transmitter, and the square wave for the circuit would draw around 100mA of current. To be safe, we aimed to supply around 90mA of current. | ||
+ | |||
+ | We attached 5 4V 80mA solar panels, wired in parallel to create a 4V 400mA system, to the batteries at the junction between the batteries and Arduino. The positive end of the solar panels was wired with a diode to prevent current from the batteries flowing the wrong way into the panels. The way the panels were wired they would provide energy to either the circuit, if it needed it, or to recharging the batteries. | ||
+ | |||
+ | There were two main issues with the power. The first issue was the fact that the voltage supplied from the batteries was 7.2V while the power supply we had been using to run tests on the Arduino had been producing 9V. Although the Arduino functions fine on 7.2V, testing indicated that the output ADC voltage values we were getting from the circuit were different when running on 7.2V Since there was no way to directly check the values coming out of the ADC, we struggled to establish the appropriate threshold values to discern when the chair was occupied or not. | ||
+ | |||
+ | The second issue with the power was the fact that the solar panels that we got were not powerful enough to recharge the batteries in a timely manner. The current supplied by the panels meant that the batteries would end up draining faster than they could be recharged. In the future more powerful solar panels could prevent this from happening. | ||
+ | |||
+ | [[File:Batterychaircircuit.png|frameless|The system of batteries and Solar Panels used to power the Arduino.]] | ||
+ | ''<small>Figure 1.5 - The battery and solar panel system used to power the Arduino.</small>'' | ||
+ | |||
+ | === Module #2: Relay occupancy data to Arduino in format for easy processing on Pi=== | ||
+ | |||
+ | ==== 2.1 Use RF communication to send data from one Arduino to another ==== | ||
+ | In order to relay data between the Arduino on the bottom of the chair and the Arduino attached to the Raspberry Pi we purchased a pair of 433Hz transmitter/receiver modules (https://www.sparkfun.com/products/10532 and https://www.sparkfun.com/products/10534). We encoded transmission and reception using the virtualWire library (https://www.pjrc.com/teensy/td_libs_VirtualWire.html). We started out using sample code from http://www.instructables.com/id/RF-315433-MHz-Transmitter-receiver-Module-and-Ardu/ , and for our final code borrowed from http://forum.arduino.cc/index.php?topic=3256.0 as well. We wired up the modules with help from https://www.sparkfun.com/datasheets/RF/KLP_Walkthrough.pdf . The final code we used to transmit and receive occupancy data can be found here https://docs.google.com/document/d/1ttIRGPHdjRMQ3Y-W13mnZI5xyS1DVvmGeYv2uDjGT6I/edit on page 3. We designed a protocol whereby the chair number and the occupancy data relating to that chair can be sent in 1 byte: if the chair is unoccupied we transmit the chair number, and if the chair is occupied we transmit the chair number plus 128. | ||
+ | |||
+ | The wiring of the receiver to the Arduino can be seen in Figure 2.2 (and also at https://www.sparkfun.com/datasheets/RF/KLP_Walkthrough.pdf) | ||
+ | |||
− | |||
− | |||
− | |||
− | |||
− | |||
[[File:Rftransmitterchaircircuit.png|frameless|Figure 2.1 - The RF Transmitter used to send data from the Arduino that detects occupancy to the Arduino connected to the Raspberry Pi.]] | [[File:Rftransmitterchaircircuit.png|frameless|Figure 2.1 - The RF Transmitter used to send data from the Arduino that detects occupancy to the Arduino connected to the Raspberry Pi.]] | ||
''<small>Figure 2.1 - The RF Transmitter used to send data from the Arduino on the chair to the Arduino connected to the Raspberry Pi</small>'' | ''<small>Figure 2.1 - The RF Transmitter used to send data from the Arduino on the chair to the Arduino connected to the Raspberry Pi</small>'' | ||
− | |||
− | + | [[File:exhibitB.jpeg|frameless|Exhibit B - the wiring of the receiver module]] | |
− | + | ''<small>Figure 2.2 - the wiring of the receiver module</small>'' | |
− | + | ==== 2.2 Communicate from the Arduino to the Raspberry Pi ==== | |
− | + | Communication from the 'receiver' Arduino to the Raspberry Pi was done through a serial connection using code from http://www.instructables.com/id/Raspberry-Pi-Arduino-Serial-Communication/ . | |
− | |||
− | |||
− | |||
− | + | '''Receiver python code on Raspberry Pi:''' | |
− | + | import serial <br /> | |
+ | ser = serial.Serial('/dev/ttyACM0',9600) <br /> | ||
+ | s = [0] <br /> | ||
+ | while True: <br /> | ||
+ | read_serial=ser.readline() <br /> | ||
+ | s[0] = str(int (ser.readline(),16)) <br /> | ||
+ | ] <br /> | ||
− | + | '''Transmitter code on Arduino''' | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | void setup() { <br /> | |
+ | Serial.begin(9600); //Starts serial communication <br /> | ||
+ | } <br /> | ||
+ | void loop() { <br /> | ||
+ | a++; // a value increase every loop <br /> | ||
+ | sprintf(dataString,"%02X",a); // convert a value to hexa <br /> | ||
+ | Serial.println(dataString); // send the data <br /> | ||
+ | delay(1000); // give the loop some break <br /> | ||
+ | } <br /> | ||
− | + | === Module #3: Use data input to create user-friendly web interface=== | |
− | + | ==== 3.1 Acquiring a domain ==== | |
− | + | The first step was acquiring the domain. We chose librarychair205.com for our domain. In order to directly upload HTML code, we needed a subdomain so we could directly post the code to have the output displayed on the website. To accomplish this, we created the subdomain chairchecker.librarychair205.com. We then uploaded the html code (https://docs.google.com/document/d/1eLf9cjyiuui8RCJtnyxFEOdVULFR5kwQXv4FLjGFs-E/edit?usp=sharing), and the website, which was static at this point, was displayed. | |
− | |||
− | |||
− | |||
− | |||
− | + | ====3.2 Coding using HTML==== | |
+ | HTML was a completely new language for us, so we used tutorials by w3schools.com (https://www.w3schools.com/html/) to get a general understanding. After tinkering around with creating boxes with text and uploading images, we realized it may be difficult to completely build a website from scratch. | ||
− | + | After researching online ways to easily create a clean user interface, we found bootstrap templates. Bootstrap is a free resource, that provides templates with accompanying HTML code. We used a bootstrap template to shape our website. This is the link to the bootstrap template we used: http://blacktie.co/2013/10/munter-one-page-theme/. | |
− | + | We stripped away all unnecessary parts of the bootstrap code, and then replaced their color scheme and images to create a map of our prototype library layout. To do so we also added a box image for the “front desk”, replaced their icon with our chair images, changed the text, and added a front door to the library. We then created two different text boxes, one that was green and read “vacant” and another that was red and read “occupied”. The occupied box was hidden for our static site at this point. The code for the final interface can be found here (https://docs.google.com/document/d/1eLf9cjyiuui8RCJtnyxFEOdVULFR5kwQXv4FLjGFs-E/edit?usp=sharing) and this is the final webpage display (http://chairchecker.librarychair205.com). | |
− | + | '''The Website Display''' | |
− | |||
− | |||
− | |||
− | |||
− | + | [[File:WebsiteDisplay.png|frameless|Website Display]] | |
− | |||
− | |||
− | |||
− | + | ====3.3 Making a dynamic webpage==== | |
+ | We found the easiest way to have the Pi communicate with the online server was to use an online database as the middleman. We used a service called Firebase, where we could type code to differentiate the different state of each chair - when it received a signal indicating the chair was seated in, the database would change the chair with the matching ID to have a value “true”, and the website would read “Occupied” in a red box above the chair. If it received information saying otherwise, the database would set the value to “false”, and the website would read “Vacant” in green box above the chair. | ||
− | + | In order to have the database change the website, it first needed an input. To do so, we created a python program that could pull in input from the Arduino (this code can be found here https://docs.google.com/document/d/1eLf9cjyiuui8RCJtnyxFEOdVULFR5kwQXv4FLjGFs-E/edit?usp=sharing). The Arduino would send in a number which corresponded to a specific chair ID, and the state of the chair. Our program took in that number, and had the Pi transmit the information to the database by opening a corresponding URL that altered the database. The URLs had the following format: webpage address/chairs/*chair ID*/*chair state*. The asterisks represent chair data, the webpage is http://chairchecker.librarychair.com/ | |
− | |||
− | |||
− | + | A shortcoming of our project was that anyone who typed in the specific URL could access the database and alter its information. We didn’t see this as too much as a problem, though, because each chair’s state was rewritten with the correct information every few seconds, and also who would want to interfere with a library chair interface. | |
− | + | '''The Dynamic Portion of our HTML Code''' | |
− | Our | + | [[File:DynamicSite.png|frameless|The Dynamic Portion of Our HTML Code ]] |
− | |||
− | |||
− | |||
− | |||
=Results= | =Results= | ||
− | + | We successfully demoed our project and accomplished the most important goals that we set for ourselves. The circuit/Arduino accurately and consistently detected when people were sitting in the chair. The Arduino on the chair communicated cleanly with the Arduino connected to the Pi, and the Raspberry Pi accurately and dynamically updated an attractive web interface. We also successfully changed which chair on the interface got updated depending on a 'chair number' which we assigned to the chair, and could easily be changed. People were impressed by our demonstration and I think saw the potential of rolling out our project on a wider scale. | |
+ | |||
+ | Instead of having an instant response on our website when someone sat down in the chair, we created a 15-30 second lag between the occupancy status of the chair changing and that change being registered on the website. Taking this time enabled us to use a rolling average filter on the Arduino. We feel that the lag is important because it adds accuracy, and in real world application, a small lag is an insignificant delay compared to stretches of that time chairs are in or out of use. | ||
+ | |||
+ | One goal that our group did not accomplish was powering the circuit solely through batteries/solar. We got the solar panels and batteries hooked up and were able to run the Arduino on power from the batteries and panels but the output voltages that we were getting from the circuit were different than what we were getting when running the Arduino through a power cord. It was difficult to discern what the output voltage threshold value is for occupied/vacant when running the circuit solely on battery power, as we could not simultaneously have a serial connection. Perhaps we could have run diagnostic tests on this by re-soldering the ADC to a separate Arduino and seeing what output voltages we were getting. | ||
+ | |||
+ | Another goal that we were not able to accomplish was using the TI board provided by Professor Morley. These boards could only be coded for using unfamiliar assembly code, and their specific IDE was very opaque and hard to use. Online support for TI microcontrollers does exist, but it is a lot less comprehensive than the online Arduino community is, and eventually we made the choice to use Arduinos instead even though they might use slightly more power. | ||
− | |||
− | |||
− | Other than the | + | Other than the power source issue there were no problems with the chair, and other than that and not using the TI boards we met all of our goals. The circuit consistently was able to detect proximity to the human body, and the Arduino was consistently able to tell what voltages represented occupation and non-occupation and transmit that to the Arduino connected to the Raspberry Pi. The Pi was consistently able to update the server which in turn was constantly able to update the website. Although there were a lot of independent moving parts in the project, they all came together harmoniously and worked to produce a working chair. |
− | [ | + | [[File:finalposter.png|frameless|Our final poster on display at the demo.]] |
[[Category:Projects]] | [[Category:Projects]] | ||
[[Category:Fall 2017 Projects]] | [[Category:Fall 2017 Projects]] |
Latest revision as of 12:46, 12 December 2017
Contents
- 1 Overview
- 2 Team Members
- 3 Objectives
- 4 Challenges
- 5 Gantt Chart
- 6 Budget
- 7 Group Presentation
- 8 Design and Solutions
- 8.1 Module #1: Detect whether someone is in the chair
- 8.1.1 1.1 Construct RC circuit that outputs variable voltage depending on total capacitance
- 8.1.2 1.2 Manage voltage flow going into circuit
- 8.1.3 1.3 Measure voltage flow exiting circuit, and analyze to determine occupancy
- 8.1.4 1.4 Integrate Arduino and circuit and attach to chair
- 8.1.5 1.5 Power the Arduino/circuit with solar power and batteries
- 8.2 Module #2: Relay occupancy data to Arduino in format for easy processing on Pi
- 8.3 Module #3: Use data input to create user-friendly web interface
- 8.1 Module #1: Detect whether someone is in the chair
- 9 Results
Overview
It's a Wednesday night. You're sitting in your room watching Netflix, putting off studying for your exam next week. You're cozy in bed, and it's cold and dark outside, plus your suite-mate just said he's ordering Domino's and there might be a slice or two left over for you. Every fiber of your being is willing you to stay home, eat, and watch TV, but that nagging voice in the back of your head tells you that you're a Wash U student damnit, and you'd better take this exam seriously! So you muster up some energy and get the kid on your floor who is in the class with you to walk to the library and study for a bit. When you guys get there, though, you see that every seat in the library is taken! ARGH!!
Few things are more annoying than when you decide to actually go study but then can't because there isn't an open spot for you in the library. Enter the Library Chair. In simple terms the Library Chair system consists of an interactive chair and a web interface. The chair can detect when someone is sitting in it, and this information is then relayed (via a few Arduinos and a Raspberry Pi) to a website which displays a map of all the chairs in the library and which ones are occupied. You can check this website from the safety and comfort of your own room; no more cold walks to the library that end up being futile!
For more specific information on how the system operates, please look at the "Design and Solutions" section of this wiki.
Team Members
Nick Blenko
Tom Howe
Josh Zucker
Our wonderful TA, Mo Wu
And our adviser, Professor Morley
Objectives
Our group's main objective was to create an interface that library goers could use to see which seats in the library are available, and which are occupied. This interface is dependent on voltage data obtained from a circuit hooked up to an Arduino and affixed to the bottom of a library chair. When a human body moves close to the circuit, i.e when someone sits down in the chair, the output voltage changes and chair occupancy can thus be determined. This circuit then communicates occupancy and location data to another Arduino connected to a Raspberry Pi. The Raspberry Pi will in turn communicate this data to a web server. We aim for the circuit/Arduino device to be accurate, low energy, and powered by solar panels.
As individuals we are simultaneously working on a few different smaller goals. These include: finalizing the circuit that will detect when someone is sitting in the chair, figuring out how to communicate effectively between the Arduinos and how to generate the wave function necessary for the circuit to operate from an Arduino, integrating a solar power source into the circuit, communicating data from the Raspberry Pi to a web server, and designing and implementing an aesthetically pleasing web interface.
Challenges
- Learning how to use the TI microcontrollers. This proved to be too difficult, so we adapted and used Arduinos instead.
- Rebuilding the circuit after someone burned it in the lab
- Getting accurate current and voltage readings from solar panels/batteries
- Needing to find a new ADC solution after realizing the built in Arduino ADC was not powerful enough
- Creating a simple button program to get our web page to react to a button pushed from the Pi
- Trial and error with making website dynamic (attempting with PHP, trying HTML-code-writing code, creating text files and uploading them as input, and finally using an online database)
Gantt Chart
Budget
- Chair: Cost Varies - (donated by Professor Morley)
- Raspberry Pi: $35.00
- Solar cells: $8.69
https://www.amazon.com/gp/product/B073Y67Z5L/ref=oh_aui_detailpage_o03_s00?ie=UTF8&psc=1
- Resistors/Capacitors/Diodes: (provided by school)
- Wire: (provided by school)
- Web Server: $12/Year
- Bluehost Account $3.99/Month
- RF Link Receiver (433 MHz) $4.95
https://www.sparkfun.com/products/10532
- RF Link Transmitter (433 MHz) $3.95
https://www.sparkfun.com/products/10534
- 2x Arduino Uno - one provided by school, one bought at link below for $27.95
https://www.amazon.com/gp/product/B008GRTSV6/ref=oh_aui_detailpage_o03_s00?ie=UTF8&psc=1
- External 16 bit ADC converter 14.95
https://www.adafruit.com/product/1085
- Rechargeable Batteries $19.98
https://www.amazon.com/gp/product/B00HZV9TGS/ref=oh_aui_detailpage_o03_s00?ie=UTF8&psc=1
Total: $139.44 (Total assumes 1 year subscription to web server and 3 month subscription to bluehost account)
Group Presentation
Design and Solutions
Module #1: Detect whether someone is in the chair
1.1 Construct RC circuit that outputs variable voltage depending on total capacitance
We first have a regular RC circuit with one metal plate acting as a parallel plate capacitor, where the other plate is effectively the rest of the universe. When a human body comes close to the circuit, its electric field increases the capacitance of this plate. This increased capacitance increases the time constant of the RC circuit, which means that in the same interval of time this altered circuit does not output a voltage as close to its peak voltage as it did before. In other words, when a human body is close to the circuit, it outputs a lower voltage.
Figure 1.1 - The circuit used to detect occupancy based on peak voltage in the circuit.
1.2 Manage voltage flow going into circuit
After prototyping on the NI Elvis, we determined that the best form of input voltage to the circuit would be a 5V square wave with a frequency of around 800kHz and a duty cycle of 50%. (For help prototyping on an NI Elvis board see our tutorial https://classes.engineering.wustl.edu/ese205/core/index.php?title=Use_a_NI_Elvis_board). Since a square wave is always either ‘on’ or ‘off’, this input means that the capacitor is always either charging or discharging, which lets us get more consistent output voltage readings from the circuit. We determined the optimal frequency through trial and error and striking a balance between signal magnitude and signal noise: using a higher input frequency led to a noisier output voltage signal, but using a lower frequency led to less of a change in voltage.
800kHz is an extremely high frequency, though, considering that the Arduino Uno CPU has a clock speed of 16MHz, so we searched for a library that could be of use and found this: https://forum.arduino.cc/index.php?topic=117425.0 . However, we struggled to implement it correctly, and further testing showed that we would only need a frequency of around 50-70 kHz.
We used pulse width modulation on the Arduino's digital pin number 6 (as seen in Figure 1.1) to supply this square wave. The default frequency for pulse width modulation on digital pin 6 is 976.56 Hz, and the default voltage is 5V. In order to increase this frequency, we reduced the PWM prescaler value on the TCCR0B timer register to 1 from a default of 64, thereby increasing the frequency by a factor of 64. (For reference see: https://arduino-info.wikispaces.com/Arduino-PWM-Frequency)
Here is the code we used to generate the 5V 63kHz square wave input:
void setup() {
pinMode(6,OUTPUT); //initializes function generator pin
TCCR0B = TCCR0B & B11111000 | B00000001; // sets timer 0 divisor to 1, freq=62.5kHz
}
void loop() {
analogWrite(6,128); //sets up square wave with duty=50%
}
1.3 Measure voltage flow exiting circuit, and analyze to determine occupancy
We initially tried to use the Arduino's built in 10-bit analog-to-digital converter (ADC) to detect changes in output voltage from the circuit. Using the minimum reference voltage of 1.1V and 1023 'steps' of specificity (2^10 = 1024), gave us a step size of ~1mV. Since we were dealing with changes in voltage (voltage when chair is occupied vs voltage when chair is vacant) on the order of microvolts, we needed another solution. We found a compatible 16-bit external ADC (https://www.adafruit.com/product/1085) and wired it up as shown in Figure 1.2. This converter has about 65,000 'steps' of specificity (2^16~65000), enabling detection of voltage changes as small as 0.0002V. We wired in a differential connection to the external converter, which is more favorable than a single-ended connection when trying to reduce noise. In order to accurately interpret this very noisy data, we had to implement a multi-tiered rolling average filter to smooth the data. The exact voltage cutoff values signifying either occupancy or vacancy are dependent on the composition and the environment of the chair, and as such need to be tested for and updated whenever the circuit is affixed to a new chair or the chair is moved.
The code to read in voltages using the external converter and then determine vacancy/occupancy using multi-tiered filters can be found here: https://docs.google.com/document/d/1ttIRGPHdjRMQ3Y-W13mnZI5xyS1DVvmGeYv2uDjGT6I/edit?usp=sharing
Figure 1.2 - The external 16-bit analog-to-digital converter used to take voltage readings from the circuit
1.4 Integrate Arduino and circuit and attach to chair
We used a solderless breadboard to connect the Arduino to the RC circuit, the external ADC converter, and an RF transmitter. We made these connections as shown in Figure 1.1, Figure 1.2, and Figure 2.1. The circuit/Arduino system is shown in Figure 1.3. In order to improve the aesthetics of the system, we designed and 3D printed a case (Figure 1.4) to cover up all the wires and circuitry. We then screwed this case to the underside of the chair, and put the metal plate from the RC circuit inside the stuffing of the chair in order to get readings most effectively.
Link to Thingiverse with Case CAD files
Figure 1.3 The circuit/Arduino system. Figure 1.4: A rendering of the case for the Arduino and circuit.
1.5 Power the Arduino/circuit with solar power and batteries
In order to power the Arduino our plan was to use a system of batteries and solar panels. The batteries are the main source of power to the Arduino and the solar panels recharge the batteries.
We ended up using 6 1.2V 2400mAh batteries (https://www.amazon.com/gp/product/B00HZV9TGS/ref=oh_aui_detailpage_o02_s00?ie=UTF8&psc=1), wired in series to create a 7.2V 2400mAh system (the recommended input voltage for the Arduino uno is 7V-12V). We also connected 7 680 Ohm resistors wired in parallel to avoid overheating and to regulate the supply of current to the Arduino. When testing with the NI Elvis and an ammeter the system was drawing around 70mA of current but according to information from various datasheets, we had estimated that powering the ADC converter, the RF transmitter, and the square wave for the circuit would draw around 100mA of current. To be safe, we aimed to supply around 90mA of current.
We attached 5 4V 80mA solar panels, wired in parallel to create a 4V 400mA system, to the batteries at the junction between the batteries and Arduino. The positive end of the solar panels was wired with a diode to prevent current from the batteries flowing the wrong way into the panels. The way the panels were wired they would provide energy to either the circuit, if it needed it, or to recharging the batteries.
There were two main issues with the power. The first issue was the fact that the voltage supplied from the batteries was 7.2V while the power supply we had been using to run tests on the Arduino had been producing 9V. Although the Arduino functions fine on 7.2V, testing indicated that the output ADC voltage values we were getting from the circuit were different when running on 7.2V Since there was no way to directly check the values coming out of the ADC, we struggled to establish the appropriate threshold values to discern when the chair was occupied or not.
The second issue with the power was the fact that the solar panels that we got were not powerful enough to recharge the batteries in a timely manner. The current supplied by the panels meant that the batteries would end up draining faster than they could be recharged. In the future more powerful solar panels could prevent this from happening.
Figure 1.5 - The battery and solar panel system used to power the Arduino.
Module #2: Relay occupancy data to Arduino in format for easy processing on Pi
2.1 Use RF communication to send data from one Arduino to another
In order to relay data between the Arduino on the bottom of the chair and the Arduino attached to the Raspberry Pi we purchased a pair of 433Hz transmitter/receiver modules (https://www.sparkfun.com/products/10532 and https://www.sparkfun.com/products/10534). We encoded transmission and reception using the virtualWire library (https://www.pjrc.com/teensy/td_libs_VirtualWire.html). We started out using sample code from http://www.instructables.com/id/RF-315433-MHz-Transmitter-receiver-Module-and-Ardu/ , and for our final code borrowed from http://forum.arduino.cc/index.php?topic=3256.0 as well. We wired up the modules with help from https://www.sparkfun.com/datasheets/RF/KLP_Walkthrough.pdf . The final code we used to transmit and receive occupancy data can be found here https://docs.google.com/document/d/1ttIRGPHdjRMQ3Y-W13mnZI5xyS1DVvmGeYv2uDjGT6I/edit on page 3. We designed a protocol whereby the chair number and the occupancy data relating to that chair can be sent in 1 byte: if the chair is unoccupied we transmit the chair number, and if the chair is occupied we transmit the chair number plus 128.
The wiring of the receiver to the Arduino can be seen in Figure 2.2 (and also at https://www.sparkfun.com/datasheets/RF/KLP_Walkthrough.pdf)
Figure 2.1 - The RF Transmitter used to send data from the Arduino on the chair to the Arduino connected to the Raspberry Pi
Figure 2.2 - the wiring of the receiver module
2.2 Communicate from the Arduino to the Raspberry Pi
Communication from the 'receiver' Arduino to the Raspberry Pi was done through a serial connection using code from http://www.instructables.com/id/Raspberry-Pi-Arduino-Serial-Communication/ .
Receiver python code on Raspberry Pi:
import serial
ser = serial.Serial('/dev/ttyACM0',9600)
s = [0]
while True:
read_serial=ser.readline()
s[0] = str(int (ser.readline(),16))
]
Transmitter code on Arduino
void setup() {
Serial.begin(9600); //Starts serial communication
}
void loop() {
a++; // a value increase every loop
sprintf(dataString,"%02X",a); // convert a value to hexa
Serial.println(dataString); // send the data
delay(1000); // give the loop some break
}
Module #3: Use data input to create user-friendly web interface
3.1 Acquiring a domain
The first step was acquiring the domain. We chose librarychair205.com for our domain. In order to directly upload HTML code, we needed a subdomain so we could directly post the code to have the output displayed on the website. To accomplish this, we created the subdomain chairchecker.librarychair205.com. We then uploaded the html code (https://docs.google.com/document/d/1eLf9cjyiuui8RCJtnyxFEOdVULFR5kwQXv4FLjGFs-E/edit?usp=sharing), and the website, which was static at this point, was displayed.
3.2 Coding using HTML
HTML was a completely new language for us, so we used tutorials by w3schools.com (https://www.w3schools.com/html/) to get a general understanding. After tinkering around with creating boxes with text and uploading images, we realized it may be difficult to completely build a website from scratch.
After researching online ways to easily create a clean user interface, we found bootstrap templates. Bootstrap is a free resource, that provides templates with accompanying HTML code. We used a bootstrap template to shape our website. This is the link to the bootstrap template we used: http://blacktie.co/2013/10/munter-one-page-theme/.
We stripped away all unnecessary parts of the bootstrap code, and then replaced their color scheme and images to create a map of our prototype library layout. To do so we also added a box image for the “front desk”, replaced their icon with our chair images, changed the text, and added a front door to the library. We then created two different text boxes, one that was green and read “vacant” and another that was red and read “occupied”. The occupied box was hidden for our static site at this point. The code for the final interface can be found here (https://docs.google.com/document/d/1eLf9cjyiuui8RCJtnyxFEOdVULFR5kwQXv4FLjGFs-E/edit?usp=sharing) and this is the final webpage display (http://chairchecker.librarychair205.com).
The Website Display
3.3 Making a dynamic webpage
We found the easiest way to have the Pi communicate with the online server was to use an online database as the middleman. We used a service called Firebase, where we could type code to differentiate the different state of each chair - when it received a signal indicating the chair was seated in, the database would change the chair with the matching ID to have a value “true”, and the website would read “Occupied” in a red box above the chair. If it received information saying otherwise, the database would set the value to “false”, and the website would read “Vacant” in green box above the chair.
In order to have the database change the website, it first needed an input. To do so, we created a python program that could pull in input from the Arduino (this code can be found here https://docs.google.com/document/d/1eLf9cjyiuui8RCJtnyxFEOdVULFR5kwQXv4FLjGFs-E/edit?usp=sharing). The Arduino would send in a number which corresponded to a specific chair ID, and the state of the chair. Our program took in that number, and had the Pi transmit the information to the database by opening a corresponding URL that altered the database. The URLs had the following format: webpage address/chairs/*chair ID*/*chair state*. The asterisks represent chair data, the webpage is http://chairchecker.librarychair.com/
A shortcoming of our project was that anyone who typed in the specific URL could access the database and alter its information. We didn’t see this as too much as a problem, though, because each chair’s state was rewritten with the correct information every few seconds, and also who would want to interfere with a library chair interface.
The Dynamic Portion of our HTML Code
Results
We successfully demoed our project and accomplished the most important goals that we set for ourselves. The circuit/Arduino accurately and consistently detected when people were sitting in the chair. The Arduino on the chair communicated cleanly with the Arduino connected to the Pi, and the Raspberry Pi accurately and dynamically updated an attractive web interface. We also successfully changed which chair on the interface got updated depending on a 'chair number' which we assigned to the chair, and could easily be changed. People were impressed by our demonstration and I think saw the potential of rolling out our project on a wider scale.
Instead of having an instant response on our website when someone sat down in the chair, we created a 15-30 second lag between the occupancy status of the chair changing and that change being registered on the website. Taking this time enabled us to use a rolling average filter on the Arduino. We feel that the lag is important because it adds accuracy, and in real world application, a small lag is an insignificant delay compared to stretches of that time chairs are in or out of use.
One goal that our group did not accomplish was powering the circuit solely through batteries/solar. We got the solar panels and batteries hooked up and were able to run the Arduino on power from the batteries and panels but the output voltages that we were getting from the circuit were different than what we were getting when running the Arduino through a power cord. It was difficult to discern what the output voltage threshold value is for occupied/vacant when running the circuit solely on battery power, as we could not simultaneously have a serial connection. Perhaps we could have run diagnostic tests on this by re-soldering the ADC to a separate Arduino and seeing what output voltages we were getting.
Another goal that we were not able to accomplish was using the TI board provided by Professor Morley. These boards could only be coded for using unfamiliar assembly code, and their specific IDE was very opaque and hard to use. Online support for TI microcontrollers does exist, but it is a lot less comprehensive than the online Arduino community is, and eventually we made the choice to use Arduinos instead even though they might use slightly more power.
Other than the power source issue there were no problems with the chair, and other than that and not using the TI boards we met all of our goals. The circuit consistently was able to detect proximity to the human body, and the Arduino was consistently able to tell what voltages represented occupation and non-occupation and transmit that to the Arduino connected to the Raspberry Pi. The Pi was consistently able to update the server which in turn was constantly able to update the website. Although there were a lot of independent moving parts in the project, they all came together harmoniously and worked to produce a working chair.