10. Input Devices

Group Assignment

In this part we measured the level of a push button in its two states, normal and pressed. The push button (normally open) is connected to Vcc through 10kOhm resistor, so in its normal state the level will be 5 V (digitally high). When pressed the level will be 0 V (digitally low).

Using the digital multimeter, in the normal state the measured value is 5.05 V (digitally 1 or high), and when pressed, the measured value is -0.3 mV (digitally 0 or low).

We used oscilloscope to measure the same input signal. To connect the oscilloscope probe, connect the spring loaded end (hock or clamp) to GND and the pin head to test point, which is the push button signal.

Note that voltage scale is 2 V/division and time scale is 1 s/division. In the normal state, the signal height is 2.5 vertical divisions, which equals to 5V (2.5 divisions x 2 V/division). When the button is pressed, the level drop to fit over the zero line. The button had been pressed for 4 seconds (4 horizontal divisions x 1 s/division).

Week Assignment

File Download

Development Board Eagle files

For individual week assignment, there are two parts. In the first part I will use HC-SR501 PIR Sensor. The second part is extra material using a breadboard and some sensors I got from old devices. In both parts I will use a development board I built in a previous week.

ATtiny44 Development Board

I built the development board based on ATtiny44 micro-processor with 20MHz ceramic resonator. I added two LEDs with limiting resistors, ISP connector, FTDI connector and male connectors to all pins.

Using the male connector this board can be used on a breadboard. All pins (including VCC and GND) were routed to the male connector, only XTAL1 (PB0) and XTAL2 (PB1) were excluded. LEDs are connected to PA5 and PA6.

Arduino UNO Replacing FTDI Cable

Due to COVID-19 lock down, we don’t have access to fablab. I will use the Arduino UNO board and Arduino serial monitor/Python serial GUI to display customized messages as input devices status changes.

Step 1: Remove the ATmega328P micro-controller from the board.
Step 2: Connect Rx, Tx pins in Arduino board to Tx, Rx pins of the FTDI connector in the development board.
Step 3: Connect Vcc, GND pins in Arduino board to Vcc, GND pins in the development board.
Step 4: Make sure to match the Baud Rate of the Arduino serial monitor/Python serial GUI to the value used in code.

Note that the jumper in the FABTinyISP is still bridged. When connecting the Arduino board and programmer cables to USB ports, and connecting ISP cable between FABTinyISP and development board, all boards (Arduino, FABTinyISP and Development) will have the same Vcc and GND as computer USB.

Week Assignment Part 1: HC-SR501 PIR Sensor

File Download

HC-SR501 PIR Sensor Datasheet
PIR Sensor C, Makefile and Python files

In this part I will work on the HC-SR501 PIR sensor. I will connect the sensor to the development board using female-to-female wires with connectors and use the Arduino UNO board to replace the FTDI cable. Event will be displayed using GUI python application.

HC-SR501 PIR Sensor

The HC-SR501 sensor is a passive infrared sensor used as motion detector. “It basically consists of two main parts: A Pyroelectric Sensor and A special lens called Fresnel lens which focuses the infrared signals onto the pyroelectric sensor. A Pyroelectric Sensor actually has two rectangular slots in it made of a material that allows the infrared radiation to pass.” Sorce

“When the sensor is idle, i.e. there is no movement around the sensor; both slots detect the same amount of infrared radiation, resulting in a zero output signal. But when a warm body like a human or animal passes by; it first intercepts one half of the PIR sensor, which causes a positive differential change between the two halves. When the warm body leaves the sensing area, the reverse happens, whereby the sensor generates a negative differential change. The corresponding pulse of signals results in the sensor setting its output pin high.” Sorce


Sorce

“There are two potentiometers on the board to adjust a couple of parameters:
Sensitivity– This sets the maximum distance that motion can be detected. It ranges from 3 meters to approximately 7 meters. The topology of your room can affect the actual range you achieve.
Time– This sets how long that the output will remain HIGH after detection. At minimum it is 3 seconds, at maximum it is 300 seconds or 5 minutes.” Sorce

The sensor has 3 pins (VCC, GND and OUT). VCC and GND are connected to Vcc and GND pins in development board (which are connected by board routing to Vcc and GND pins in programmer through the ISP header and cable), and OUT is connected to PB2.

Problems and Fixes!: hello.HC-SR501.py

This program starts a graphical user interface that displays a message and color code related to sensor reading. The code communicates serially with the board through the FTDI cable and USB. I faced some problems while trying to work on this file and at the end I solved them. The source of these problems was that the original code was written using Python2 and I am using Python3.

Step 1: Download the file hello.HC-SR501.py. You should have Python installed to your computer. Connect FTDI cable and check in devices the right COM port number, mine was COM6

Step 2: Open Windows “Command Prompt” and change path to where you saved the Python file. Type “Python hello.HC-SR501.py COM6” and hit enter. There is a syntax error in line45: Missing parentheses in call to ‘print’ in print “command line: hello.HC-SR501.py serial_port”. Open the Python file and add parentheses to the print command.

Step 3: Type “Python hello.HC-SR501.py COM6” and hit enter. A new error appears in line 17: ModuleNotFoundError: No module named ‘Tkinter’. The right module name is “tkinter” with a small t. Change it in Python file.

Step 4: Type “Python hello.HC-SR501.py COM6” and hit enter. A new error appears in line 18: ModuleNotFoundError: No module named ‘serial’. We need to install the right serial module to Python, which is “pySerial” not “serial”.

Step 5: Type “pip uninstall serial” and hit enter. This will remove this module if it is installed. Then type “pip install pySerial”.

Step 6: In line 28, change the if sentence from “if (char == ‘1’)” to “if (int(char) == 1)”.

Step 7: Type “Python hello.HC-SR501.py COM6” and hit enter. Now everything should be working fine.

Hero Shoot!

Week Assignment Part 2 (Extra Material): Breadboard and Arduino Board as FTDI Cable

File Download

Photomicrosensor EE-SA102 Datasheet
Rotational Switch (input 1) C and Makefile
Photomicrosensor (input 2) C and Makefile
IR Sensor (input 3) C and Makefile

Input Device #1: Rotational Spring-Return Double NO Switch

It has two normally-open switches (NO-COM-NO). Pins (2, 3, 4) are common and internally connected. If switch rotated to the left, the (NO-COM) through pin1 will be closed. If switch rotated to the right, the (COM-NO) through pin5 will be closed. Both switches cannot be closed at the same time. The switch is spring-returned to center position, leaving both switches open.

To interface the switch to the development board, I used two 10 kOhm resistors to externally pull-up the switches. When a switch is open, the input to micro-processor will be HIGH, and when a switch is closed it will be LOW. The rotational switch outputs are connected to PA2 and PA3 pins in the development board.

Pins PA2 and PA3 from the development board side are defined as inputs with internal pull-up resistors disabled. Development board LEDs status will change according to sensor value, and also a message will be displayed on the Arduino serial monitor. Remember to write the lfuse using the command defined in Makefile, because clock divider set to one using bit CKDIV8 in lfuse byte. The code snippet below shows the main function, the other functions are to communicate with the serial monitor in one direction onto (writing to monitor).

int main(void) {
    double Tdebounce = 100;

    //Clock divider set to one using lfuse bit CKDIV8 = 1

    //Serial
    DDReg |= (1 << Rx);
    DataReg |= (1 << Rx);

    //Board LEDs
    DDRA |= (1 << PA5); //Right LED
    DDRA |= (1 << PA6); //Left LED

    //Input devices
    DDRA &= ~(1 << PA2); //Switch right
    DDRA &= ~(1 << PA3); //Swtich left

    WriteMsg("FabAcademy 2020 Input devices!\n");

    while(1){
        if(!(PINA & (1 << PINA2))){ //Switch right
            _delay_ms(Tdebounce);
            PORTA |= (1 << PA5);
            WriteMsg("Switch position: Right\n");
            while(!(PINA & (1 << PINA2))){}
        }

        else if(!(PINA & (1 << PINA3))){ //Swtich left
            _delay_ms(Tdebounce);
            PORTA |= (1 << PA6);
            WriteMsg("Switch position: Left\n");
            while(!(PINA & (1 << PINA3))){}
        }

        else{
            PORTA &= ~(1 << PA5);
            PORTA &= ~(1 << PA6);
            WriteMsg("Switch position: Center\n");
            while((PINA & (1 << PINA2)) && (PINA & (1 << PINA3))){}
        }
    }
}

Input Device #2: Photomicrosensor (Actuator Mounted)

Photomicrosensor consists of an emitter (infrared LED) and receiver (phototransistor). They are located opposite to each other and usually in a dark plastic casing that allows the light emitted by the LED to reach the phototransistor. The plastic casing has a slot where an object can block the emitted light and changes the conductivity of the phototransistor. Sensing phototransistor conductivity allows to determine object presence.

The photomicrosensor number is EE-SA102 from omron. It has actuator mounted to allow and block emitted light. The normal status of the actuator and sensor is that emitted light is allowed to reach the phototransistor.

To design the driving circuit, we need to use the datasheet of the sensor.

Step 1: Starting from the emitter typical forward voltage (1.2V) and using graph1, we can find by projection 1.2V at 25C curve, the forward current is approximately 25mA. Note that this value is less than the maximum forward current (50mA).
To calculate the emitting LED limiting resistor we apply Ohm’s law 5V = 25mA x R + 1.2V. Resistor value should be 152 Ohm. The closest standard value is 150 Ohm.

Step 2: Using graph2, if 25mA is passing through the emitter circuit, then approximately maximum 6mA (light current) may pass through receiver circuit. We don’t need to use the all 6mA, we will use 1mA passing in receiver circuit.
Note that and using graph3 that for forward current of 25mA and light current of 1mA, the drop voltage Vce in the phototransistor should be less than 0.5V.

Step 3: To calculate the load resistor in receiver circuit side, we apply Ohm’s law and use collector-emitter saturation voltage (0.1V typical). 5V = 1mA x R + 0.1V. R value should be 4.9 kOhm. I only found 4.7 kOhm in stuff I have. This will make the light current (5V - 0.1V) / 4.7 kOhm = 1.04 mA

Step 4: When there is no object blocking the emitter light, the output voltage will be 0.1V, and when there is an object blocking the emitter light, the output voltage will be approximately Vcc = 5V.
The table below compares between calculated values and measure values using digital multimeter. Note that these calculations assumes that Vcc = 5V.

Calculated Measured
Forward current mA 25 24.3
Forward voltage V 1.2 1.2
Light current mA 1.04 0.99
Vout with blocking object V 5 4.84
Vout w/o blocking object V 0.1 0.2

When there is an object blocking the emitting light, the input to board will be HIGH, and when there is no object blocking the emitting light the input to board will be LOW. Photomicrosensor is connected to PB2.

Pin PB2 from the development board side is defined as input with internal pull-up resistor disabled. Board LEDs will change their status and a message will be displayed on the Arduino serial monitor according to sensor value. Remember to write the lfuse using the command defined in Makefile, because clock divider set to one using bit CKDIV8 in lfuse byte. The code snippet below shows the main function, the other functions are to communicate with the serial monitor in one direction onto (writing to monitor).

int main(void) {
    double Tdebounce = 100;
    char eventFlag = 0;

    //Clock divider set to one using lfuse bit CKDIV8 = 1

    //Serial
    DDReg |= (1 << Rx);
    DataReg |= (1 << Rx);

    //Board LEDs
    DDRA |= (1 << PA5); //Right LED
    DDRA |= (1 << PA6); //Left LED

    //Input devices
    DDRB &= ~(1 << PB2); //photomicrosensor

    WriteMsg("FabAcademy 2020 Input devices!\n");

    while(1){
        if(!(PINB & (1 << PINB2))){
            _delay_ms(Tdebounce);
            WriteMsg("Photomicrosensor: Unblocked\n");
            PORTA |= (1 << PA5);
            PORTA |= (1 << PA6);
            eventFlag = 1;
            while(!(PINB & (1 << PINB2))){}
        }
        if(eventFlag == 1){
            eventFlag = 0;
            PORTA &= ~(1 << PA5);
            PORTA &= ~(1 << PA6);
            WriteMsg("Photomicrosensor: Blocked\n");
        }
    }
}

Input Device #3: IR Sensor Module

I used the IR sensor to measure proximity. I couldn’t find any datasheet so I wrote a simple code and measured the distance at which the sensor detects objects. Depending on object surface and color, the IR sensor can detect objects that are 10 mm - 30 mm away.

The IR sensor module output is connected to PA7. The input pin will measure the logic level of the sensor output, and when object is detected (output = HIGH), a message will be displayed in the Arduino module.

Pin PA7 from the development board side is defined as input with internal pull-up resistor disabled. Board LEDs will change their status and a message will be displayed on the Arduino serial monitor according to sensor value. Remember to write the lfuse using the command defined in Makefile, because clock divider set to one using bit CKDIV8 in lfuse byte. The code snippet below shows the main function, the other functions are to communicate with the serial monitor in one direction onto (writing to monitor).

int main(void) {
    double Tdebounce = 100;

    //Clock divider set to one using lfuse bit CKDIV8 = 1

    //Serial
    DDReg |= (1 << Rx);
    DataReg |= (1 << Rx);

    //Board LEDs
    DDRA |= (1 << PA5); //Right LED
    DDRA |= (1 << PA6); //Left LED

    //Input devices
    DDRA &= ~(1 << PA7); //IR

    WriteMsg("FabAcademy 2020 Input devices!\n");

    while(1){
        if((PINA & (1 << PINA7))){ //Object detected
            _delay_ms(Tdebounce);
            PORTA |= (1 << PA5);
            PORTA |= (1 << PA6);
            WriteMsg("IR: Object detected\n");
            while((PINA & (1 << PINA7))){}
        }

        else{
            PORTA &= ~(1 << PA5);
            PORTA &= ~(1 << PA6);
            WriteMsg("IR: No objects detected\n");
            while(!(PINA & (1 << PINA7))){}
        }
    }
}

Hero Shoot!

Input Device #1: Rotational Spring-Return Double NO Switch

Input Device #2: Photomicrosensor (Actuator Mounted)

Input Device #3: IR Sensor Module