Skip to content

11. Input devices

This week I worked on defining my final project idea and started to getting used to the documentation process.

Group Assignment

Link

We measured the analog value of a Temperature sensor using a multimeter. A multimeter is an electronic measuring instrument that combines several measurement functions in one unit. A typical multimeter can measure voltage, current and resistance. The analog input device we are measuring using the multimeter is a Low Voltage Temperature Sensor TMP36 .

As per the datasheet, we will find that it need to be powered by a voltage of (2.7 V to 5.5 V) and is calibrated directly in degrees celcius. Meaning the values we get with a simple conversion coorisponde to celcieus degree values.

i5

The first step is to connect the tempreture sensor to the supply voltage. The data sheet shows the correct way to connect. The data sheet also has a graph showing the voltage level at every tempreture. form this graph we can conclude that the tempreture in celcieus equals 100*(reading in V) - 50.

i6

I powered on the tempreture sensor using Arduino board and connected the data pin & ground to the multimeter. I set the multimeter to the VDC setting.

i1

i2

The voltage is 0.749V, lets calculate the tempreture. Temp = (0.749 * 100 ) - 50 = 24.9 degrees celcius, which is around room tempreture so it makes sense. I touched the tempreture sensor with my hand & the voltage started increasing because of my hands heat.

i4

i3

It reached 0.793 v.

Temp = (0.793 * 100 ) - 50 = 29.3 degrees celcius

Accelerometer

I used The GY-521 module. It is a breakout board for the MPU-6050 MEMS (Microelectromechanical systems) that features a 3-axis gyroscope, a 3-axis accelerometer, a digital motion processor (DMP), and a temperature sensor.

The MPU 6050 is a sensor based on MEMS (micro electro mechanical systems) technology. Both the accelerometer and the gyroscope are embedded inside a single chip. This chip uses I2C (inter-integrated circuit) protocol for communication.

I2C is a serial protocol for two-wire interface to connect low-speed devices like microcontrollers, EEPROMs, A/D and D/A converters, I/O interfaces and other similar peripherals in embedded systems. It was invented by Philips and now it is used by almost all major IC manufacturers.

How it works

An accelerometer works on the principle of the piezoelectric effect. Imagine a cuboidal box with a small ball inside it, like in the picture above. The walls of this box are made with piezoelectric crystals. Whenever you tilt the box, the ball is forced to move in the direction of the inclination due to gravity. The wall that the ball collides with creates tiny piezoelectric currents. There are three pairs of opposite walls in a cuboid. Each pair corresponds to an axis in 3D space: X, Y, and Z axes. Depending on the current produced from the piezoelectric walls, we can determine the direction of inclination and its magnitude. Reference link

Datasheet

Since the accelorometer has a 3-axis with digital I2C & SPI interface. I had to check if Attiny44 supports it. I found that it has Digital Communication Peripherals:1-SPI, 1-I2C from this link. From datasheet: SCL: Two-wire mode Serial Clock for USI Two-wire mode.

d1 d2

Circuit Design

I used Eagle software to do the design. I used the circuit design from week 7 but removed the button & added a header to use it to connect the accelorometer to the circuit.

e4

At first I was planning on doing the routing from scratch.

e1 e2 e3

However, took a lot of time, so I decided to modify the previous board.

e5

Then I replaced the header 6 pin header with a 8 pin header for more stability.

e7 e6 e8

The final tracing & boarder PNG images

e9 e10

Eagle Board (right click + Save link as)

Eagle Schematic (right click + Save link as)

RML file 1 (right click + Save link as)

RML file 2 (right click + Save link as)

Circuit Milling & Soldering

I followed the same steps as in week 5 .

e11 e12 e13 e14 e17

It looks like my FTDI connector should have been resting on the pcb (for mechanical support) and not floating on air. I made it this way because I was afraid that the connector might not have enough space to connect. This can be solved by allocating a bigger edge on the board.

Reading

The difficult part was that there were not many resourses about using Attiny44 with accelerometer & some of my previous failed. This was my last attempt & it was successful. We used this Youtube video as a refrence & made some modifications to the code.

e16

#include <TinyWireM.h>
#include <SoftwareSerial.h>
// #define DEBUG 1  // - uncomment this line to display accel/gyro values
#ifdef DEBUG
#endif

int accelX, accelY, accelZ;
int gyroX, gyroY, gyroZ;
int gyroXold, gyroYold, gyroZold;
char mpu = 0x68;  

SoftwareSerial Monitor(PA1, PA0);  // We will only use Tx on PortB 4

void setup() {
  Monitor.begin(9600);
  TinyWireM.begin();
  delay(1000); // Display title

  // We need to do three things.  1. Disable sleep mode on the MPU (it activates on powerup).  2. Set the scale of the Gyro.  3. Set the scale of the accelerometer
  // We do this by sending 2 bytes for each:  Register Address & Value
  TinyWireM.beginTransmission(mpu); 
  TinyWireM.write(0x6B); //  Power setting address
  TinyWireM.write(0b00000000); // Disable sleep mode (just in case)
  TinyWireM.endTransmission();
  TinyWireM.beginTransmission(mpu); 
  TinyWireM.write(0x1B); // Config register for Gyro
  TinyWireM.write(0x00000000); // 250° per second range (defau<)
  TinyWireM.endTransmission();
  TinyWireM.beginTransmission(mpu); //I2C address of the MPU
  TinyWireM.write(0x1C); // Accelerometer config register
  TinyWireM.write(0b00000000); // 2g range +/- (defau<)
  TinyWireM.endTransmission();
}

void loop() {
  getAccel();
  getGyro();
  Monitor.print((long)accelX);
  Monitor.print("   ");
  Monitor.print(accelY);
  Monitor.print("   ");
  Monitor.println(accelZ);
  }



void getAccel() {
  TinyWireM.beginTransmission(mpu); //I2C address of the MPU
  TinyWireM.write(0x3B); //  Acceleration data register
  TinyWireM.endTransmission();
  TinyWireM.requestFrom(mpu, 6); // Get 6 bytes, 2 for each DoF
  accelX = TinyWireM.read() << 8; // Get X upper byte first
  accelX |= TinyWireM.read();     // lower
  accelY = TinyWireM.read() << 8; // Get Y upper byte first
  accelY |= TinyWireM.read();     // lower
  accelZ = TinyWireM.read() << 8; // Get Z upper byte first
  accelZ |= TinyWireM.read();     // lower
}

void getGyro() {
  TinyWireM.beginTransmission(mpu); //I2C address of the MPU
  TinyWireM.write(0x43); // Gyro data register
  TinyWireM.endTransmission();
  TinyWireM.requestFrom(mpu, 6); // Get 6 bytes, 2 for each DoF
  while (TinyWireM.available() < 6);
  gyroX = TinyWireM.read() << 8; // Get X upper byte first
  gyroX |= TinyWireM.read();     // lower
  gyroY = TinyWireM.read() << 8; // Get Y upper byte first
  gyroY |= TinyWireM.read();     // lower
  gyroZ = TinyWireM.read() << 8; // Get Z upper byte first
  gyroZ |= TinyWireM.read();     // lower
}

bool shaken() {
  if ((abs(accelX) > 20000) || (abs(accelY) > 20000) ||  (abs(accelZ) > 32760)) {
  return true;
  }
  else return false;
  }

bool stirred() {
  gyroXold = gyroX;    // Save current Gyro settings...
  gyroYold = gyroY;
  gyroZold = gyroZ;
  getGyro();  // get a second reading to compare with the last to see if we're moving
  //  300 is just a number to fi<er noise-level fluxuations .. DYOR
  if (((gyroX - gyroXold) > 300) || ((gyroY - gyroYold) > 300) ||  ((gyroZ - gyroZold) > 300)) {
    return true;
  }
  else return false;
}

The blue graph represents the X axis

The green graph represents the Z axis

The red graph represents the Y axis