Skip to content

12. Input Devices

This week we learned about sensors and input devices that are generally used to collect real-time data from the physical environment. These data is usually sent to Microcontrollers or other devices to be analyzed and perform actions. Some of the input devices Neil showed us during the global lecture are:

  • Switches
  • Potentiometers. (level of resistance)
  • Step Response.
  • Thermistors. (Temperature)
  • Phototransitors. (Light)
  • GPS. (Location/Time)
  • Accelerometers / Gyroscopes. (Acceleration, Orientation, Rotation)
  • Microphones. (Sound)
  • Cameras. (Images)

Input devices design

I decided to experiment with Temperature and Light sensors during this week, so I started with the examples Neil showed us on the global lecture.

Temp board traces

Light board traces

Both designs are very similar, since both of them contains the following components:

  • Attiny45 mcu.
  • 1 uF capacitor
  • 10k Ohm resistors.
  • ISP and FTDI connectors.

The temperature sensor board contains 3 aditional 10k Ohm resistors and a NTC (negative temperature coefficient) thermistor. NTC thermistors demonstrate a negative temperature coefficient of resistance, which is done through a decrease in resistance proportionate to temperature increase (there is a non-linear relationship between temperature and resistance). On the other hand, RTDs (resistance temperature detectors) exhibit a positive temperature coefficient; they increase the resistance of a device as the temperature increases.

The light sensor board includes a Visible Light Phototransistor. Additionally, there was also IR phototransistors in our inventory; which are just “normal” phototransistors with a built-in filter which blocks visible light while passing IR.

I noticed that in both boards, the PB0 and PB1 pins could be used for connecting additional components… So I decided to include leds to notify changes in the signals.

I opened eagle and used Neil’s boards for reference and then included the leds. In the case of the Temperature sensor, I added an orange led for notifying high temperatures and a white led for low temperatures. On the other hand, I added a white led to the Light sensor that should be turned on when there’s not enough light in the room.

Light sensor schematic

Light sensor traces

Temp sensor schematic

Temp sensor traces

Milling and stuffing

After designing the boards in Eagle, I exported the gerber files and opened them in FlatCAM to generate the gcodes.

Edgar built a CNC machine for milling circuit boards, so I gave it a try with a simplified version of the Temp sensor. This machine uses a V shaped endmill. It was the first time I used this type of endmill and unfortunately I set the Z axis incorrectly… which caused that some traces end up broken.

Edgar's CNC machine

First attempt

Then I jumped to our Roland MODELA PRO II MDX-540 Milling Machine and milled both boards.

Results

I wrote down the list of components for each board on a piece of paper and put the components on it. And finally, I soldered the components to the boards.

Components list

Boards

Programming

After soldering all the components to both boards I loaded Neil’s example codes to see if they work. In order to do that I:

  1. Created a folder for this week on my linux partition: mkdir week12 and cd week12
  2. Created subfolders for both boards: mkdir temp and mkdir light
  3. Copied hello.temp.45.c, hello.temp.45.make and hello.temp.45.py to the temp folder.
  4. Copied hello.light.45.c, hello.light.45.make and hello.light.45.py to the light folder.
  5. Connected the temp board to my programmer board and to the FTDI cable; Connected the programmer board and the FTDI cable to my laptop; and finally ran: sudo make -f hello.temp.45.make program-usbtiny.
  6. Opened a separated terminal and ran python3 hello.temp.45.py /dev/ttyUSB0 to show the signals on my laptop screen.
  7. Similarly, for the light sensor, I connected the light board and ran: sudo make -f hello.light.45.make program-usbtiny and python3 hello.light.45.py /dev/ttyUSB0 in a separated terminal to show the results.

Then, in order to turn on the leds I added to both boards, I modified Neil’s codes to calculate the Temperature and Light levels in the same way he did in the python scripts and added if clauses to turn on the leds.

// hello.temp.45.c (Modified)

#include <avr/io.h>
#include <util/delay.h>
#include <math.h>

...

// Define Led Ports
#define LED1_PORT PB1
#define LED2_PORT PB0



void put_char(volatile unsigned char *port, unsigned char pin, char txchar) {
   ...
}

int main(void) {

   ...

   // Auxiliary variables for temperature calculation
   float eps = 0.5;
   float filter = 0.0;
   int low = 0;
   int high = 0;
   int value = 0;
   float V = 0.0;
   float R = 0.0;
   float B = 0.0;
   float T = 0.0;
   float R25 = 0.0;

   // Set Led ports as outputs
   DDRB |= (1 << LED1_PORT); // Orange Led
   DDRB |= (1 << LED2_PORT); // White Led

   while (1) {

      ...

      // Temperature value calculation
      low = (int)ADCL;
      high = (int)ADCH;
      value = 256*high + low;

      if (value > 511){
         value -= 1024;
      }

      V = 2.5 - value*5.0/(20.0*512.0);
      R = 10000.0/(5.0/V-1.0);

      // NHQ103B375R5
      // R25 10000 (O)
      // B (25/85) 3750 (K)
      // R(T(C)) = R(25)*exp(B*(1/(T(C)+273.15)-(1/(25+273.15))))
      B = 3750.0;
      R25 =  10000.0;
      T = 1.0/(log(R/R25)/B+(1/(25.0+273.15))) - 273.15;
      filter = (1-eps)*filter + eps*T;

      // Turn on Orange Led when temperature is higher than 27 degrees celsius
      if(filter > 27){
         PORTB |= (1 << LED1_PORT);
      } else {
         PORTB &= ~(1 << LED1_PORT);
      }

      // Turn on Orange Led when temperature is lower than 25.5 degrees celsius
      if(filter < 25.5){
         PORTB |= (1 << LED2_PORT);
      } else {
         PORTB &= ~(1 << LED2_PORT);
      }

   }
}
// hello.light.45.c (Modified)

#include <avr/io.h>
#include <util/delay.h>

...

// Define Led Ports
#define LED1_PORT PB0


void put_char(volatile unsigned char *port, unsigned char pin, char txchar) {
   ...
}

int main(void) {
   ...

   // Auxiliary variables for temperature calculation
   float eps = 0.5;
   float filter = 0.0;
   int low = 0;
   int high = 0;
   int value = 0;

   // Set Led port as output
   DDRB |= (1 << LED1_PORT);


   //
   // main loop
   //
   while (1) {
     ...
      // Light level value calculation
      low = (int)ADCL;
      high = (int)ADCH;
      value = 256*high + low;
      filter = (1-eps)*filter + eps*value;

      // Turn on white Led when light level is higher than 500
      if(filter > 500){
         PORTB |= (1 << LED1_PORT);
      } else {
         PORTB &= ~(1 << LED1_PORT);
      }

      }
   }

Surprisingly, when I loaded the codes into my boards, the white leds didn’t work. I suspected that -for some reason- the PB0 couldn’t be used as output… Then I noticed I soldered the white leds in the wrong direction… I desoldered both leds and put them in the right way and it worked!

Light sensor HERO video
Temp sensor HERO video

Files


Last update: April 26, 2022