Home / Lab 9

Lab 9

The questions below are due on Friday April 10, 2020; 05:15:00 PM.
You are not logged in.

If you are a current student, please Log In for full access to the web site.
Note that this link will take you to an external site (https://shimmer.csail.mit.edu) to authenticate, and then you will be redirected back to this page.

1) Overview

In this lab, you will make a card reader that causes your MIT ID card to transmit its internal code, including your personal ID number!

Note that this lab will take around 3 hours, and thus spill into next week's lab session. Accordingly, it is due next Friday. There is a Lab next Friday as well, which will take about 1 hour, and thus you should aim to complete up thru Checkoff 2 of this Lab 9 in order to be on track for next week.

2) Preliminaries

Make sure you have completed the [prelab](COURSE/prelab9) before you attempt today's lab!

Before starting the following parts of the lab, check that your function generator is in High-Z mode by pressing Shift, Enter, the right arrow three times, and the down arrow twice. If it shows 50 Ohm, use the left or right arrows and Enter to switch the signal generator to High-Z.

3) Introduction

As explained in the prelab, your MIT ID is a proximity card, or “prox card”, containing an integrated circuit (IC) that is powered by picking up nearby oscillating electromagnetic fields. The card readers at doorways produce 125-kHz oscillating electromagnetic fields. When powered, the IC, through an antenna in the prox card, transmits a signal at 0.5 and 1.5 times the incoming signal frequency. Thus, for an incoming signal at 125 kHz, the prox card transmits at 62.5 kHz and 187.5 kHz. Our goal today is to recover the data encoded on the signal transmitted at 62.5 kHz using the card reader outlined below.

Our card reader comprises three parts: a pair of coils, analog electronics, and the Teensy. The first coil (TX) transmits the 125-kHz signal that powers the prox card. The second coil (RX) receives the 62.5-kHz signal, and unfortunately the 125-kHz and 187.5-kHz signals as well. At the output of the receiving coil, the 125-kHz signal will be large while the 62.5-kHz signal will be small; the 187.5-kHz signal will also be quite small, and can be ignored. Therefore, in order to successfully read the data encoded onto the 62.5-kHz signal it is necessary to greatly attenuate the 125-kHz signal while amplifying the 62.5-kHz signal. The plan here is to use a notch filter for attenuation and an op-amp amplifier for amplification, both of which you should have already designed in the pre-lab. With the help of a comparator not shown in the figure, the filtered and amplified signal can then be read by the Teensy which interprets the signal and displays the ID card data on the OLED screen!

Now let’s build and demonstrate the card reader. Here are the steps of the lab:

  1. Build and test the coils. In the process we will ensure good inductive coupling to the prox card, and that the prox card transmits a signal.
  2. Build the notch filter and tune the prox card transmit frequency to best match the filter notch.
  3. Add in the op-amp amplifier designed in prelab.
  4. Add in a comparator to turn the processed analog signal into a digital signal that can be read and interpreted by the Teensy. The Teensy will then display the card information on the OLED screen!

4) Coils

4.1) Build the Coils

The first task is to make two coils of wire. You can check first on the staff table if there are any premade coils to use (just remember to return them in the end!) or wind your own coils following the steps below.

  • Take two different strands of standard lab hookup wire from the large spools, each about 2 m in length. Choose one color for your transmitter (TX) coil and the other for your receiver (RX) coil.

  • Cut and strip both wires at their ends and then wrap them into ~5 cm-diameter coils. Try to leave about 20 cm of loose wire at the ends to wrap around each coil in order to hold the coils together; see image below.

  • You will use both coils stacked on top of one another, as shown in the image below.

4.2) Analyze FFT

Now verify that your coils can inductively couple signals between themselves like a transformer. To do this, connect the function generator to the TX coil, and set it to produce a 125-kHz sinusoidal voltage with 20 V peak-to-peak amplitude. The TX coil will then create an alternating magnetic field that can be picked up by the RX coil. Connect your scope probes across the RX coil as shown in the schematic diagram below to observe the received signal.

To enable signal coupling, lay the RX coil on top of the TX coil. You should see a signal induced in the RX coil on the oscilloscope. Adjust the coils to maximize the induced signal. Verify that you can produce ~1 V_{pp} across the receiver coil. Observe how the signal drops off as you separate the coils and/or rotate them relative to each other. Measure the period and thus calculate the frequency of the induced signal and enter the frequency in units of kHz here.

Enter the frequency(kHz):

Now observe the received signal in the frequency domain. On the oscilloscope, select Math Menu \rightarrow Operation \rightarrow FFT. The oscilloscope will now display the Fourier Transform of the received signal. While the secrets of the Fourier Transform may not be apparent without having taken 6.003, it is sufficient to know here that the Fourier Transform permits you to observe the frequency components present in a signal. So, for a sinusoid oscillating at a single frequency, we expect to see a single pulse at that frequency, as shown below.

When in the Math menu, make sure that the source is set to the channel used to display the received signal, and set the FFT Zoom to X1. Use the SEC/DIV dial to set the x-axis to 25 kHz. You should then see a peak near the middle of your screen, corresponding to the 125-kHz signal. Vary the frequency of the signal generator and verify that the peak moves to the left and right as you would expect. You may need to use the POSITION knob in the time base menu of the oscilloscope if things are offset along the x-axis for any reason. After varying its frequency, set the signal generator back to 125 kHz.

4.3) Insert MIT ID

Carefully, without disturbing the coil positions, lay your MIT ID (prox) card on top of the two coils. You can also try sliding your card between the two coils. Prox cards contain integrated circuits that are powered by picking up power from nearby oscillating magnetic fields. The card readers at doorways create these 125 kHz oscillating magnetic fields (exactly like the field coming from your signal generator coil right now!)

When exposed to the 125-kHz signal, your prox card will harvest power from the signal generator and use it to power its integrated circuit (IC). Once powered, the IC will transmit a signal at 0.5 and 1.5 times the incoming signal frequency. So, if the incoming signal is at 125 kHz, the IC will transmit at 62.5 kHz and 187.5 kHz. Can you observe these new signals in the Fourier Transform? Insert and remove the card a few times to verify that the effect is real. Take another card which does not contain an RFID, for example a credit card, and observe whether it behaves in the same way.

What do you expect the time domain signal to look like? Switch to the time domain by pressing the MATH MENU button again to get rid of the FFT, and verify your predictions; be sure to set your trigger appropriately so you “freeze” the signal. It should look much the same as it did before the prox card was inserted, but you might note a slight asymmetry introduced into the 125-kHz signal. If you don’t see the asymmetry yet, don’t worry; that is what our filter is for!

Checkoff 1:
Demonstrate the coil response with and without a prox card to a staff member.

5) Filter & Amplifier

5.1) Build the Notch Filter

To improve the visibility of the 62.5-kHz signal relative to the 125-kHz signal, we use the notch filter designed in the prelab.

Build the filter on an open section of your breadboard; you should remove everything except the Teensy and the OLED screen. Use 47 mH for the inductor, 51 k\Omega for the resistor, and your value calculated in the prelab for the capacitor.

TIP: You will get a nicer notch if you lay down the inductor as depicted in the image below:

Place one oscilloscope probe across the input of the filter and another across the output of the filter. Look at the two signals on the oscilloscope. You should constantly check to make sure your coils are in position. If they move while you are doing the experiment, just move them back; a binder clip might be useful here. You may remove the prox card for this part of the experiment, just to keep things simple.

5.2) Tuning

Now, select MATH MODE \rightarrow Operation \rightarrow FFT again and view the oscilloscope channel connected to the filter output. Change the signal generator frequency by small increments until you start to see the center peak become attenuated and drop in amplitude; 1-kHz increments should be small enough. You should see the amplitude drop by several decibels at the filter notch frequency (aim for a 1 division drop, which is approximately 10dB), which is the natural frequency of the LC resonator. Once you have found the rough notch frequency of your filter, switch to 100-Hz or smaller increments on the signal generator, and scan even more carefully to find a more precise value for the notch frequency. Record the notch frequency of your filter.

Below is an animation demoing the frequency sweep performed to determine the notch frequency. Focus on the tallest peak and do not worry about the other side bands that are present due to aliasing. Find the frequency at which the peak is minimized. If you are having trouble finding the minimum, adjust your coils or your inductor (to reduce parasitics due to the environment) until you have at least a -10dB (one division drop) in the peak at the notch frequency. If you are having a lot of trouble finding your center frequency, ask a 6.002 staff member for help!

Going forward, we will power the prox card with a signal at the notch frequency measured above. In this way the notch filter will remove the powering signal. Even though prox cards are designed to work with a powering frequency of 125 kHz, they are very tolerant to variations in that frequency. However, if your notch frequency is below 75 kHz or above 175 kHz, hence requiring a powering frequency outside this range, then the IC in your ID card could have problems responding. So, change the capacitor in your filter as needed to move the notch frequency to within the range of 75 kHz to 175 kHz, preferably close to 125 kHz.

5.3) Build the Amplifier

You may have noticed that at resonance, there is almost no signal coming out of the notch filter. This is why we also designed an op-amp amplifier in the prelab. Recall that we designed for a gain of 20 (this may end up being too much gain. In deployment you may need to back that gain way down depending on how well your coil was wound). Now comes the task of actually wiring it up and implementing that amplifier on the breadboard!

A complete schematic of the filter and amplifier is shown below. Be careful of the orientation of your op amp, and verify its connections before powering on!

To power the op-amp, use the 5V (and ground) from the Teensy (use the 'Vin' pin on the Teensy since that is connected to the USB's 5V supply. See the card here), via the USB connection. It does not matter what code is running on the Teensy.

Make sure that if you are using the breadboard rails for power, that you do not connect the 3.3V (from a previous lab) to the 5V (for this lab).

The amplifier uses a TLV2371 op amp. Its pinout is shown below:

Make sure to include a small 0.1-\muF capacitor near the power supply pin of the op-amp to help stabilize its voltage.

Once you have constructed and powered on the amplifier, take a look at its output signal:

  • Power the TX coil via the signal generator as before
  • Insert your prox card between the two coils.
  • Scope the output of the op-amp at pin 6.

How has the signal changed, and why? Consider what the sum of two sine waves (125 kHz and 62.5 kHz) would look like. Also observe the FFT of the signal and note the change. Try to get an amplifier output similar to that shown below, with the side bands approximately equal in magnitude to the center peak. You may discover there is more noise in your signal (due to aliasing from the oscilloscope’s sample rate or the not enabling the bandwidth limiting on the scope channel). Check what your signal looks like in the time domain and make sure you can distinguish two different peak heights on the amplifier output. If you are unsure about your results, talk to a staff member.

Checkoff 2:
Verify that you can see resonance in the 75-175 kHz range in time and frequency domains and show a staff member.

Our goal is to get to this point in the first lab period. If you are here, congrats! You can go home now, or keep going if you still have time remaining in the session.

6) Teensy

6.1) Data Encoding: Phase Shift Keying

Your MIT ID prox card transmits a sinusoidal signal at 62.5 kHz onto which it digitally encodes your MIT ID number and other information. It also does so at 187.5 kHz, but we will ignore that aspect of its operation. Although the topic is beyond the scope of 6.002, a basic understanding of data encoding is useful when designing your prox card reader and interpreting its signals. You may also find it interesting to understand how your MIT ID communicates its data! There are many different ways to encode binary data bits onto a sinusoidal signal, such as amplitude modulation, frequency modulation, phase modulation, and more. The basic idea is to encode the binary 0s and 1s as measurable characteristics of the sinusoid with some amount of built-in immunity to noise. In the case of the MIT ID cards, binary phase-shift keying (PSK) is used.

Briefly, in the MIT ID card implementation, 16 cycles of the 62.5-kHz sinusoid are used to encode one data bit. If a given data bit is to be the same as the previous data bit (0 following a 0, or 1 following a 1), then its 16 cycles are a simple continuation of the previous 16 cycles. If a given data bit is to be the opposite of the previous data bit (1 following a 0, or 0 following a 1) then the phase of its 16 cycles is shifted by 180 degrees such that its sign is negated for the duration of the bit. This is illustrated in the figure below, although to save space only 2 sine waves are used to encode a given data bit.

You may wonder how the Teensy can decode the signal if there is no absolute information on the values of the data bits. This is where understanding the protocol also becomes necessary. The data message begins with a very long sequence of 0s, which helps synchronize decoding. Once a long sinusoid without any phase shifts is detected, we can mark the corresponding data bits as 0s and continue reading relative to that synchronization. You do not need to worry about these details as they are handled by the Teensy code provided for this lab.

6.2) Digitizing the Card Signal

The signal features critical to data decoding are the phase shifts of the 62.5-kHz sinusoidal signal transmitted by the prox card. The amplifier output is a combination of the 62.5-kHz signal, the original 125-kHz signal, and a 187.5-kHz signal, all of nearly the same amplitude. Ignoring the 187.5-kHz signal because it only adds small ripples, we can visualize the amplifier output by summing a sinusoid (yellow) at frequency f with another synchronous sinusoid (purple) at frequency f/2 that contains a phase shift. The result (blue) is shown in the graphs below.

From the blue graph above it is evident that one effect of phase shifting is to stretch out the time difference between the peaks. Thus, by counting and timing peaks it is possible to identify data bits and decode them. The Teensy, with its precision internal timers, is very good at this. However, to help the Teensy, it is desirable to sharpen the peaks so they are easily identified. One easy way to do this is with a comparator. In our implementation, the comparator will be pulled high when its input is below a set threshold, and pulled low when its input exceeds the same threshold indicating that a peak is found. The Teensy will trigger an interrupt on a high to low transition of the output and measure the time elapsed between triggers as part of its decoding process. The graph below shows the desired behavior, with the input in blue, the threshold in red, the comparator output in green, and the trigger signal as green arrows.

For this method to work, the threshold must be tuned precisely to catch the peak but ignore any other noise or ripple, so we will implement the threshold using a potentiometer to avoid needing to find a perfect resistor combination. The potentiometer forms a resistive voltage divider such that the threshold can range from 0 V to 5 V. When tuning the threshold, it is recommended to connect an oscilloscope probe to both comparator inputs and set them to the same voltage division, such that the threshold is between the two peaks. Note that a more sophisticated peak detector would employ hysteresis for noise immunity, but that is not necessary here.

The comparator we will use is the LM311, with the pinout from its datasheet shown below. You can leave the balance/strobe pins disconnected, but you must make sure that both the GND and V_{EE} pins are connected to ground. While the Teensy doesn’t have any code uploaded on it, you also need to provide a pull-up resistor, 18k\Omega from the output to 5V. The reasoning behind this is not covered in this class, but you can read more about it in the datasheet or on this site. Once the code is uploaded in the next section, we can use the Teensy’s internal pull-up setting and remove the pull-up resistor. Using the internal pull-up also ensures that the output is brought to the proper 3.3-V level.

The complete circuit schematic is shown in the image below. Add the comparator and potentiometer (use your 10k pot) to your breadboard implementation and connect the output of the comparator to the Teensy’s pin A6; check your Teensy pinout card to find the correct pin location.

Power the circuit as before and place your ID on the coils. Use four oscilloscope probes to replicate the images shown below by scoping at the points shown by the colorful dots above. Your scope traces should look a lot like the waveforms we graphed earlier.

Note: depending on the accuracy of your filter tuning, you may end up seeing a waveform that looks more like the following:

This is also ok, as long as you can distinguish between the ‘short and high peaks’ with the comparator, since they represent the 62.5 kHz signal. Turn the potentiometer to tune the threshold to lie between the two different peak amplitudes. If you capture a single shot, you should be able to catch the extended time delay resulting from the phase shift (two short peaks instead of one).

6.3) Teensy Code

Now that we have all of the electronics set up, we just need to integrate the Teensy. The 5-V power for your circuit and the comparator output pin should already be connected to the Teensy.

Be careful of what voltages you have on the ‘rail’ and make sure the OLED is being powered via 3.3 V and NOT 5 V.

Once wired, upload this week’s code here and scan your ID card. If everything is built and tuned properly, the OLED should recognize your ID as an MIT ID card, but leave the user as unknown. If you have time, move onto the last step to update the code to recognize your own ID number!

Checkoff 3:
Show your card reader to a staff member, and demonstrate that it is able to recognize an MIT ID card.

Now, go on to Lab 10. If you have time after finishing Lab 10, please try the optional section below.

6.4) Optional: Read Your Own Personal ID

To identify your personal bits, we have created another Teensy script to stream every bit it reads. Analyzing this repeating string of bits, the 6.002 staff has identified patterns and isolated which bits correspond to individuals and which ones are constant. The protocol is as follows. First we look for 30 zeros, which helps us align the bits; remember, with phase-shift keying we cannot otherwise know the absolute value of the bits. The 30 zeros are followed by 22 constant bits, which for an MIT ID are: 1000001110011000010110. Then come the 33 personal bits, which are unique to your card. Finally, there are 139 more constant bits, which MIT could configure for each user, based on the protocol specified by the card manufacturer. But, MIT happens to leave them constant. An example bit stream is shown below (note the image is a bit wrong...the final chunk is 139 bits long...not 172).

This total of 224 bits are repeated endlessly while the prox card is powered. The Teensy print-all code here will stream this sequence into the serial monitor; make sure you match the baud rate of 115200. Upload this code and let it run for a while with the serial monitor open; 10 secs should be plenty. You should see the screen updating a row of bits. Copy and paste your data into any text editor to be able to take a closer look at it and break up the segments. You should be able to identify the blocks of 30x 1’s or 0’s. If they are 1’s, either invert every bit as you read them off, or rerun the Teensy code and hope that it guesses correctly this time. Then count off the 22 constant bits. You should verify that they match the MIT constant mentioned above.

Prox card security has been criticized as being low relative to magnetic strip security because one might generate a stand-off system that could read the card’s ID number. Given what you’ve shown here, perhaps you are better equipped to judge for yourself whether this is a legitimate concern.