Skip to content

11. Input devices

For this week:

individual assignment:
measure something: add a sensor to a microcontroller board
that you have designed and read it
group assignment:
probe an input device’s analog levels and digital signals

Individual assignment

Buck regulator


For this week I designed an Attiny44 powered buck Regulator. I Need voltage regulator (from 5V to 3.3V) For my final project.

In a variety of sensors, the output is an analog variable voltage. This analog signal can be read by analog to digital converter using a microprocessor.

In the Attiny44A is an analog to digital converter that can read analog voltage between 0-5.5V. The ADC voltage reference and at the same time the maximum readable voltage can be adjusted to Vcc, external by connecting voltage reference to Aref pin, and to 1.1V internally. The ADC can read 7 different single-ended analog pins by multiplexing. The resolution can be adjusted to 8-bit or higher 10-bit resolution.

In designed buck regulator there are tree analog sensors. Setting potentiometer, output voltage, and shunt resistor voltage. The potentiometer, shunt resistor and output voltage act as an analog sensor.

The potentiometer creates a voltage between Vcc - 0V that can be adjusted. This voltage is used as an analog signal to the ATtiny to set the regulators desired voltage.

The second analog input is the output voltage. The voltage is read as an analog signal and the output voltage is determined from the analog signal.

Third analog signal input is the voltage before the current shunt resistor. A shunt resistor is used to determine the current. Shunt resistor will be 0.5 Ohm for this design.
From Ohm’s law, V = I*R, The current flowing through resistor can be calculated by measuring the voltage from both sides of the resistor. When the resistor value(R) says the same when the current(I) rises the voltage drop(V) goes up. By measuring the analog voltage value before the shunt resistor and comparing the value to the output voltage value the voltage drop can be measured and the current can be calculated.

The selected mosfet can withstand 1.1A of current. This is the maximum the circuit will be designed on. The ADC has a 10-bit resolution on the used settings and the reference voltage is the Vcc. The voltage resolution is then: Vcc/1024 = 5V /1024 = 0.0048828125V/div. At 1.1A the readout will be: Vsunt = 1.1A * 0.5 Ohm = 0.55V That correlates to analog readout difference of : 0.55V/0.0048828125V = 112,64. The safe operation is then achieved when the difference between voltage out analog readout and shunt resistor analog readout is kept under 112 units.

The buck regulator is according to Wikipedia:

A buck converter (step-down converter) is a DC-to-DC power converter which steps down the voltage
(while stepping up current) from its input (supply) to its output (load).
It is a class of switched-mode power supply (SMPS) typically containing at least 
two semiconductors (a diode and a transistor, although modern buck converters 
frequently replace the diode with a second transistor used for synchronous rectification) 
and at least one energy storage element, a capacitor, inductor, or the two in combination.
To reduce voltage ripple, filters made of capacitors (sometimes in combination with inductors)
are normally added to such a converter's output (load-side filter) and input (supply-side filter)

Essentially it chops the input voltage into small packages and averages them out to average voltage value. The key parts of the regulator are the inductor, capacitor and the MOSFET. These are selected according to the used input voltage and maximum output voltage. The precise specs are calculated from the desired switching frequency. The exact values needs some calculations for the regulator to work.

Some back-of-the-envelope calculations for the designed buck regulator.

This board will be used for learning the whole Final project and will be used to accomplish multiple weeks of Fabacademy. Because of that the progress of making is documented in more steps.

Designing the board.

The board was drawn in Eagle same way as in the week 5 and in the week 7

Schematic for the board.

Final layout. This took alot of iterations because of the nature of high frequency signal.

The traces and out cut images for the milling.

The milling program in mods.

Settings for the milling.

Tool path seemed OK.

Bit used for milling. same as in the week 7.

The leveling of the mill was off and the board took several tries to make right.

After the milling.

This desing included holes for the capasistator. I used dremel in a press to drill the holes with 1 mm drill pit.

Finished board after drilling and steel wool buff to make the soldering easier.

After the parts were sourced and the board was soldered.

Needed parts:
* 1x Attiny44A SSU
* 1x 10 uF cap
* 20 MHz Resonator
* AVRISPSMD 2x3-pin connector header.
* 1x6-pin smd side connector.
* 1x 10k Ohm resistor Pull up resistor for header vcc.
* 3x 0 ohm resistor. Debounce voltage ladder
* 1x 10 uF Capacitor attiny44a Vcc filtering
* 1x 10 ohm outrush current limiting resistor
* 1x 470 Ohm mosfet pull up resistor.
* 1x Schottky diode.
* 1x 100 mH inductor
* 1x 0.5 Ohm shunt resistor
* 1x 10 k Ohm potentiometer.

Parts to be soldered.

Finished board.

The code for the analog sensors.

The coding was done in Arduino IDE. For the Attiny support into the Arduino IDE the SpenceKonde ATTinyCore is installed. Installation of the ATTIny Core is easy. first copy the json link into the Arduino IDE Preferences Additional Boards Manager URLs. After that the ATTinyCore can be selected from Boards manager and installed.

The board is connected to the FabTinyISP made in the week5 for programming. The power is provided by FTDI cable.

In the Arduino IDE from the Tools menu the right settings for the ATTiny44 are selected. After this the code can be uploaded to the board normally.

Settings in the Arduino IDE.

This week is focused on the input readouts. The output values and behavior is omitted and can be found in the output week

The Attiny is connected to the potentiometer, Shunt resistor and voltage out to the pins PA7, PA3 and PA2 respectively

I wanted to learn bit shifting and bit operators for register manipulation.

From the Attiny44 datasheet the needed register values for different settings and operations are looked up and the register bits are then flipped accordingly to match the desired value. These registers govern everything on the microprosessor.

For example the ADMUX is ADC Multiplexer Selection Register. It is an 8- bit register that controls the reference voltage settings and the Analog Channel multiplexing and Gain Selection.

For this code the ADC register part of the datasheet was in heavy use.

In the code the ports are set as input and the digital input is disabled.

In the loop the different analog inputs are read and written to the serial monitor with software serial.

The code with comments:

#ifndef F_CPU
#define F_CPU 20000000UL // 20 MHz clock speed

#include <avr/io.h>
#include <avr/interrupt.h>
#include <SoftwareSerial.h>         //serial ouput libary.

volatile int potread = 0;           // volatile variable for reading the potentiometer. 
volatile int VSense = 0;            // volatile variable for reading the output voltage. 
volatile int Asense = 0;            // volatile variable for reading the shunt resistor voltage. 
const int PWMPin = 8;               // output pin for the PWM signal. This infomation is from the used tinycore:
        //serial ouput libary.

SoftwareSerial mySerial(0, 1); // RX, TX  // serial to output the read analog values. 

void setup() {


  ADMUX &= ~(1<< REFS0);     // VCC used as analog reference, disconnected from PA0 (AREF)bit 0
  ADMUX &= ~(1<< REFS1);     // VCC used as analog reference, disconnected from PA0 (AREF)bit 1

  DDRA &= ~(1<<DDA7); //Make potentiometer pin an input. 
    DDRA &= ~(1<<DDA3); //Make Asense pin an input.
    DDRA &= ~(1<<DDA2); //make Vsense pin an input.

    DIDR0 |= (1<<ADC7D); // Disable digital input on port PA7
  DIDR0 |= (1<<ADC3D); // Disable digital input on port PA7
  DIDR0 |= (1<<ADC2D); // Disable digital input on port PA7

//PWM settings
  pinMode(PB2, OUTPUT);                //setting the PWM pin to output. 
        TCCR0A    |= (1<<WGM01);       // set for Fast 8-bit PWM mode
        TCCR0A    |= (1<<WGM00);        // set for Fast 8-bit PWM  mode
        TCCR0A    |= (1<<COM0A1);     //Set OC0A on         Compare MatchClear OC0A at BOTTOM        (inverting mode). Driving N-channel mosfet. 
        TCCR0A    |= (1<<COM0A0);     // Set OC0A on    Compare Match Clear OC0A at BOTTOM (inverting mode)   
        TCCR0B  |= (1<<CS00);        //clk0/O/1 (No prescaling)try to go afap. this gives a freguency of 20 000 000hz/256= 78 125hz
       TCCR0B  &= ~(1<<CS01);       //set CS01 to 0. 

   OCR0A = 255;                       // start the PWM signal from 255 value (0-255 because of the 8-bit bode). so P MOSFET is off and no power is going through.   


  void loop() {

 potread = analogRead(A7);      // Read the potentiometer value
 VSense = analogRead(A2);       // Read the ouput voltage. 
 Asense = analogRead(A3);       // Read the voltge from the shunt resistor. 

potread = potread/4;        // Scaling the 16 bit analog read to 8-bit OCR0A Fast PWM register. 
OCR0A = potread;            // setting the potentiometer value to the   PWM OCR0A control register for the Fast PWM signal.  

mySerial.print("Asense :");     // Printing the serial the analog values. 
mySerial.print(" ");
mySerial.print("VSense :");
 mySerial.print(" ");
mySerial.print("potread :");


To test the analog sensors the potentiometer is set to a medium value to get a reading. For the current sense test a resistor was soldered to the output to act as an dummy load.

Board with the dummy load.

The output voltage on given settings.

The analog sensor values are displayed on the serial monitor. Potread is the value read from the potentiometer. It changes when the potentiometer is turned.

For some odd reason the internal voltage reference seemed to be adjusted to 3.3V rather than the intended 5Vcc. This why the reading from the voltage sensors are higher than they should. Asense is reading a higher value than the Vsense as was expected. These values change as the load is increased in the output and when the duty cycle of the input is changed.

The current from the analog sensor values. (1021-982) x(3.3/1024) = 0,1257‬A. The current value seems a bit high for the given load. Next board may need dome thicker traces and equal length trace paths to the analog read in pins. and a low ERS smoothing capacitor.

The wrong voltage reference could not be changed in a given time. This needs to be corrected in future.

All of my work files can be found at my gitlab repository

Group assignment¶

Group members: Lukasz, Gleb, Marjo, Jobin and I

We decided to start with measuring signals from analog input devices using photovoltaic modules we found, they are like mini sized solar panels. We tried the differences between fluorescent lamp and Smartphone LED.

We connected our test units in series obtain higher voltage values. We used oscilloscope to measure output.

Differences are clearly visible. LED provided a stable voltage level, where overhead ceiling lamp was flickering with 50 Hz frequency.

Next we decided to work with ATTiny. We had photoresistor, which changes its resistance in presence of light. The circuit was simple - voltage divider. Value of the first resistor is fixed, where photoresistor resistance varies. Voltage across photoresistor will change depending on light strength. There are three pins, which needs to be connected. Power line (TTL logic values), ground and signal pin - output value.

We checked the values using an oscilloscope to make sure it works. The circuit was powered from the USB port. Everything worked as expected.

We created a code using Arduino IDE, which was turning LED on every time photoresistor was lacking light. Our previously designed board didn’t have pinheaders to connect with output boards, so we soldered signal line straight to unused port.

After programming circuit was supplied from the USB port. It didn’t require more than two connections, 5V and GND. It could be useful as a working principle is similar to lamps with a dusk sensor. After a couple of attempts we managed to make it fully functional.

Finally, we decided to test analog to digital version. ATtiny will send some characters depending on what it will sense with previously used photoresistor.

We modified Arduino code so that every time there will be no light detected “0” will be sent, where any voltage (create by light) above given threshold will send “1” over serial port. This would be easily readable using putty. After couple attempts we achieved it.

After a moment we decided to investigate Arduino function Serial. Wire and instead of using characters, we used ASCII codes. We picked two random numbers: “43” and “44”. It turned out that first was plus sign and second was a comma. We measured transmission using an oscilloscope. Everything worked well.

Measure point for the serial output is from the RXD pin of the FTDI cable.

Comma serial signal

Plus serial signal

Code for Arduino led toggle on photosensor trigger

Code for Arduino serial write on photosensor trigger