The assignment of this week is to work in a group to probe an input device's analog and digital signals. The individual assignment is to connect a sensor to a microcontroller board that I have designed and take readings.

This week assignment content:

Softwares used:

Datasheets:

Potentiometer connection and programming Resources:

Tilt sensor connection and programming Resources:

MPU6050 connection and programming Resources:

Thermistor “1206” connection and programming Resources:


10.1. Group assignment

For the group assignment, we have to probe an input device's analog and digital signals. Therefore, we have measured the digital signal of an ultrasonic sensor and the analog signal of a temperature sensor. Click here to enter this week group assignment.


10.2. Individual assignment: Measure something

10.2.1. Potentiometer

I have used a Trimmer Potentiometer 10kOhms to create a simple Goniometer using simple components. The potentiometer is a simple knob that provides a variable resistance, which can be read as an analog input to a microcontroller board. For my project, I will use the change in resistence as a measure of knee angle of movement. For accurate readings, calibraton is requried.

Connection:

Potentiometer has three physical pins. The middle pin is connected to the arduino analog input (A0), while the other outer pins are connected to GND and VCC.

By rotating the shaft of the potentiometer towarad the outer pin that connected to VCC, the resistence will change giving a different analog input to the middle pin (maximum reading is 1023). In the same way, by rotating the shaft toward the GND pin, the resistance will change and the analog input will change (minimum reding 0).

connection

Code:

#define ROTARY_ANGLE_SENSOR A0  //Use analog pin A0 for the Rotary Angle Sensor
#define ADC_REF 3.3             //Rreference voltage of ADC is 3.3v
#define FULL_ANGLE 300.0        //Full value of the rotary angle is 300 degrees
 
void setup()
{
  //Start the serial connection
  Serial.begin(9600);
}
 
void loop()
{
  //Read the value of the rotary angle sensor in degrees
  int degrees = getDegrees();
  
  //Output it to the serial monitor
  Serial.print("The angle between the mark and the start position: ");
  Serial.println(degrees);
  
  //The delay between readings
  delay(500);
}
 
int getDegrees()
{
  //Read the raw sensor value
  int sensor_value = analogRead(ROTARY_ANGLE_SENSOR);
  
  //Convert the sensor reading to degrees and return that value
  float voltage = (float)sensor_value * ADC_REF / 1023; 
  float degrees = (voltage * FULL_ANGLE) / ADC_REF; 
  return degrees;
}

Example of the serial monitor and plotter output:

serial_monitor

serial_plotter

Video of the operating system:


10.2.2. Tilt sensor

Tilt sensor was used to detect motion. The one I used, has a cylindrical shape with four physical pins. It has a small ball inside it, which be in contact with all four pins when the sensor is upright. When the sensor tilt more than 45 degree to any direction, the output will be OFF.

Connection:

tilt_sensor

Code:

void setup()
{
  //Start the serial connection
  Serial.begin(9600);
  pinMode(8, INPUT);
}
 
void loop()
{
  if (digitalRead(8) == 0)
  {
    //Output it to the serial monitor
    Serial.println("Tilt detected");
    delay(500); 
  }
  else
  {
    Serial.println("No tilt");
    delay(500);
  }
}

Video of the operating system:


10.2.3. Inertial Measurement Unit (IMU) - MPU6050

"MPU6050" is an inertial measurement unit (IMU) of six degrees of freedom (6DOF) that combines a 3-axis accelerometer and a 3-axis gyroscope.

mpu6050

Connection:

I have used two of them for my final project to measure the knee angle. To use two MPU6050 simultaneously, I have connected "ADO" pin of one of them to Vcc and the other to GND and called them by their addresses (0x68 and 0x69). Refer to the following image (taken from Daniels Blog) to understand the connection.

connection

I have mounted the first MPU6050 on my microcontoller board "ATtiny84", which is made to be placed on the thigh ((For design and fabrication process, refer to my Final Project >> Circuit design >> Thigh circuit >> 1.3. Third version)) and mounted the second MPU6050 on the other circuit made to be placed on the shank ((For design and fabrication process, refer to my Final Project >> Circuit design >> Shank circuit)). Arduino UNO was used as ISP to program my board. Rx pin of my microcontroller were connected to Rx pin of Arduino UNO to Receive the readings of physical movement of MPU6050 to Arduino IDE serial monitor.

circuit_connection

Notes:

  • Upload ArduinoISP code to Arduino UNO first, then upload your code using Arduino UNO to your microcontroller board.
  • Remove the connection of Rx while uploading the codes.

Code:


/* http://www.youtube.com/c/electronoobs/eng_arduino_tut76.php
 * This is an example where we configure te data of the MPU6050
 * and read the Acceleration data and print it to the Monitor monitor
 * Arduino pin    |   MPU6050
 * 5V             |   Vcc
 * GND            |   GND
 * A4             |   SDA
 * A5             |   SCL
 */

#include <TinyWireM.h>
#include <SoftwareSerial.h>
#ifdef DEBUG
#endif

//Gyro Variables
float elapsedTime, time, timePrev;        //Variables for time control
int gyro_error=0;                         //We use this variable to only calculate once the gyro data error
int gyro_error2=0;
float Gyr_rawX, Gyr_rawY, Gyr_rawZ;     //Here we store the raw data read 
float Gyr_rawX2, Gyr_rawY2, Gyr_rawZ2;
float Gyro_angle_x, Gyro_angle_y;         //Here we store the angle value obtained with Gyro data
float Gyro_angle_x2, Gyro_angle_y2; 
float Gyro_raw_error_x, Gyro_raw_error_y; //Here we store the initial gyro data error
float Gyro_raw_error_x2, Gyro_raw_error_y2;

//Acc Variables
int acc_error=0;                         //We use this variable to only calculate once the Acc data error
int acc_error2=0;
float rad_to_deg = 180/3.141592654;      //This value is for pasing from radians to degrees values
float Acc_rawX, Acc_rawY, Acc_rawZ;    //Here we store the raw data read 
float Acc_rawX2, Acc_rawY2, Acc_rawZ2;
float Acc_angle_x, Acc_angle_y;          //Here we store the angle value obtained with Acc data
float Acc_angle_x2, Acc_angle_y2;
float Acc_angle_error_x, Acc_angle_error_y; //Here we store the initial Acc data error
float Acc_angle_error_x2, Acc_angle_error_y2;

float Total_angle_x, Total_angle_y;
float Total_angle_x2, Total_angle_y2;

SoftwareSerial Monitor(PA1, PA0);

void setup() {   
  TinyWireM.begin();                           //begin the wire comunication  
  TinyWireM.beginTransmission(0x68);           //begin, Send the slave adress (in this case 68)              
  TinyWireM.write(0x6B);                       //make the reset (place a 0 into the 6B register)
  TinyWireM.write(0x00);
  TinyWireM.endTransmission(true);             //end the transmission
  //Gyro config
  TinyWireM.beginTransmission(0x68);           //begin, Send the slave adress (in this case 68) 
  TinyWireM.write(0x1B);                       //We want to write to the GYRO_CONFIG register (1B hex)
  TinyWireM.write(0x10);                       //Set the register bits as 00010000 (1000dps full scale)
  TinyWireM.endTransmission(true);             //End the transmission with the gyro
  //Acc config
  TinyWireM.beginTransmission(0x68);           //Start communication with the address found during search.
  TinyWireM.write(0x1C);                       //We want to write to the ACCEL_CONFIG register
  TinyWireM.write(0x10);                       //Set the register bits as 00010000 (+/- 8g full scale range)
  TinyWireM.endTransmission(true); 

  TinyWireM.begin();                           //begin the wire comunication  
  TinyWireM.beginTransmission(0x69);           //begin, Send the slave adress (in this case 68)              
  TinyWireM.write(0x6B);                       //make the reset (place a 0 into the 6B register)
  TinyWireM.write(0x00);
  TinyWireM.endTransmission(true);             //end the transmission
  //Gyro config
  TinyWireM.beginTransmission(0x69);           //begin, Send the slave adress (in this case 68) 
  TinyWireM.write(0x1B);                       //We want to write to the GYRO_CONFIG register (1B hex)
  TinyWireM.write(0x10);                       //Set the register bits as 00010000 (1000dps full scale)
  TinyWireM.endTransmission(true);             //End the transmission with the gyro
  //Acc config
  TinyWireM.beginTransmission(0x69);           //Start communication with the address found during search.
  TinyWireM.write(0x1C);                       //We want to write to the ACCEL_CONFIG register
  TinyWireM.write(0x10);                       //Set the register bits as 00010000 (+/- 8g full scale range)
  TinyWireM.endTransmission(true); 


  Monitor.begin(9600);                     //Remember to set this same baud rate to the serial monitor  
  time = millis();                        //Start counting time in milliseconds


/*Here we calculate the acc data error before we start the loop
 * I make the mean of 200 values, that should be enough*/
  if(acc_error==0)
  {
    for(int a=0; a<200; a++)
    {
      TinyWireM.beginTransmission(0x68);
      TinyWireM.write(0x3B);                       //Ask for the 0x3B register- correspond to AcX
      TinyWireM.endTransmission(false);
      TinyWireM.requestFrom(0x68,6); 
      
      Acc_rawX=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ; //each value needs two registres
      Acc_rawY=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ;
      Acc_rawZ=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ;

      
      /*---X---*/
      Acc_angle_error_x = Acc_angle_error_x + ((atan((Acc_rawY)/sqrt(pow((Acc_rawX),2) + pow((Acc_rawZ),2)))*rad_to_deg));
      /*---Y---*/
      Acc_angle_error_y = Acc_angle_error_y + ((atan(-1*(Acc_rawX)/sqrt(pow((Acc_rawY),2) + pow((Acc_rawZ),2)))*rad_to_deg)); 
      
      if(a==199)
      {
        Acc_angle_error_x = Acc_angle_error_x/200;
        Acc_angle_error_y = Acc_angle_error_y/200;
        acc_error=1;
      }
    }
  }//end of acc error calculation   

  if(acc_error2==0)
  {
    for(int b=0; b<200; b++)
    {
      TinyWireM.beginTransmission(0x69);
      TinyWireM.write(0x3B);                       //Ask for the 0x3B register- correspond to AcX
      TinyWireM.endTransmission(false);
      TinyWireM.requestFrom(0x69,6); 
      
      Acc_rawX2=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ; //each value needs two registres
      Acc_rawY2=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ;
      Acc_rawZ2=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ;

      
      /*---X---*/
      Acc_angle_error_x2 = Acc_angle_error_x2 + ((atan((Acc_rawY2)/sqrt(pow((Acc_rawX2),2) + pow((Acc_rawZ2),2)))*rad_to_deg));
      /*---Y---*/
      Acc_angle_error_y2 = Acc_angle_error_y2 + ((atan(-1*(Acc_rawX2)/sqrt(pow((Acc_rawY2),2) + pow((Acc_rawZ2),2)))*rad_to_deg)); 
      
      if(b==199)
      {
        Acc_angle_error_x2 = Acc_angle_error_x2/200;
        Acc_angle_error_y2 = Acc_angle_error_y2/200;
        acc_error2=1;
      }
    }
  }//end of acc error calculation   
  
/*Here we calculate the gyro data error before we start the loop
 * I make the mean of 200 values, that should be enough*/
  if(gyro_error==0)
  {
    for(int i=0; i<200; i++)
    {
      TinyWireM.beginTransmission(0x68);            //begin, Send the slave adress (in this case 68) 
      TinyWireM.write(0x43);                        //First adress of the Gyro data
      TinyWireM.endTransmission(false);
      TinyWireM.requestFrom(0x68,4);           //We ask for just 4 registers 
         
      Gyr_rawX=TinyWireM.read()<<8|TinyWireM.read();     //Once again we shif and sum
      Gyr_rawY=TinyWireM.read()<<8|TinyWireM.read();
   
      /*---X---*/
      Gyro_raw_error_x = Gyro_raw_error_x + (Gyr_rawX/32.8); 
      /*---Y---*/
      Gyro_raw_error_y = Gyro_raw_error_y + (Gyr_rawY/32.8);
      if(i==199)
      {
        Gyro_raw_error_x = Gyro_raw_error_x/200;
        Gyro_raw_error_y = Gyro_raw_error_y/200;
        gyro_error=1;
      }
    }
  }//end of gyro error calculation   

    if(gyro_error2==0)
  {
    for(int ii=0; ii<200; ii++)
    {
      TinyWireM.beginTransmission(0x69);            //begin, Send the slave adress (in this case 68) 
      TinyWireM.write(0x43);                        //First adress of the Gyro data
      TinyWireM.endTransmission(false);
      TinyWireM.requestFrom(0x69,4);           //We ask for just 4 registers 
         
      Gyr_rawX2=TinyWireM.read()<<8|TinyWireM.read();     //Once again we shif and sum
      Gyr_rawY2=TinyWireM.read()<<8|TinyWireM.read();
   
      /*---X---*/
      Gyro_raw_error_x2 = Gyro_raw_error_x2 + (Gyr_rawX2/32.8); 
      /*---Y---*/
      Gyro_raw_error_y2 = Gyro_raw_error_y2 + (Gyr_rawY2/32.8);
      if(ii==199)
      {
        Gyro_raw_error_x2 = Gyro_raw_error_x2/200;
        Gyro_raw_error_y2 = Gyro_raw_error_y2/200;
        gyro_error2=1;
      }
    }
  }//end of gyro error calculation  
}//end of setup void






void loop() {
  timePrev = time;                        // the previous time is stored before the actual time read
  time = millis();                        // actual time read
  elapsedTime = (time - timePrev) / 1000; //divide by 1000 in order to obtain seconds

  //////////////////////////////////////Gyro read/////////////////////////////////////

    TinyWireM.beginTransmission(0x68);            //begin, Send the slave adress (in this case 68) 
    TinyWireM.write(0x43);                        //First adress of the Gyro data
    TinyWireM.endTransmission(false);
    TinyWireM.requestFrom(0x68,4);           //We ask for just 4 registers
        
    Gyr_rawX=TinyWireM.read()<<8|TinyWireM.read();     //Once again we shif and sum
    Gyr_rawY=TinyWireM.read()<<8|TinyWireM.read();
    /*Now in order to obtain the gyro data in degrees/seconds we have to divide first
    the raw value by 32.8 because that's the value that the datasheet gives us for a 1000dps range*/
    /*---X---*/
    Gyr_rawX = (Gyr_rawX/32.8) - Gyro_raw_error_x; 
    /*---Y---*/
    Gyr_rawY = (Gyr_rawY/32.8) - Gyro_raw_error_y;
    
    /*Now we integrate the raw value in degrees per seconds in order to obtain the angle
    * If you multiply degrees/seconds by seconds you obtain degrees */
    /*---X---*/
    Gyro_angle_x = Gyr_rawX*elapsedTime;
    /*---X---*/
    Gyro_angle_y = Gyr_rawY*elapsedTime;


    
    TinyWireM.beginTransmission(0x69);            //begin, Send the slave adress (in this case 68) 
    TinyWireM.write(0x43);                        //First adress of the Gyro data
    TinyWireM.endTransmission(false);
    TinyWireM.requestFrom(0x69,4);           //We ask for just 4 registers
        
    Gyr_rawX2=TinyWireM.read()<<8|TinyWireM.read();     //Once again we shif and sum
    Gyr_rawY2=TinyWireM.read()<<8|TinyWireM.read();
    /*Now in order to obtain the gyro data in degrees/seconds we have to divide first
    the raw value by 32.8 because that's the value that the datasheet gives us for a 1000dps range*/
    /*---X---*/
    Gyr_rawX2 = (Gyr_rawX2/32.8) - Gyro_raw_error_x2; 
    /*---Y---*/
    Gyr_rawY2 = (Gyr_rawY2/32.8) - Gyro_raw_error_y2;
    
    /*Now we integrate the raw value in degrees per seconds in order to obtain the angle
    * If you multiply degrees/seconds by seconds you obtain degrees */
    /*---X---*/
    Gyro_angle_x2 = Gyr_rawX2*elapsedTime;
    /*---X---*/
    Gyro_angle_y2 = Gyr_rawY2*elapsedTime;
    
  //////////////////////////////////////Acc read/////////////////////////////////////

  TinyWireM.beginTransmission(0x68);     //begin, Send the slave adress (in this case 68) 
  TinyWireM.write(0x3B);                 //Ask for the 0x3B register- correspond to AcX
  TinyWireM.endTransmission(false);      //keep the transmission and next
  TinyWireM.requestFrom(0x68,6);    //We ask for next 6 registers starting withj the 3B  
  /*We have asked for the 0x3B register. The IMU will send a brust of register.
  * The amount of register to read is specify in the requestFrom function.
  * In this case we request 6 registers. Each value of acceleration is made out of
  * two 8bits registers, low values and high values. For that we request the 6 of them  
  * and just make then sum of each pair. For that we shift to the left the high values 
  * register (<<) and make an or (|) operation to add the low values.
  If we read the datasheet, for a range of+-8g, we have to divide the raw values by 4096*/    
  Acc_rawX=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ; //each value needs two registres
  Acc_rawY=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ;
  Acc_rawZ=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ; 
 /*Now in order to obtain the Acc angles we use euler formula with acceleration values
 after that we substract the error value found before*/  
 /*---X---*/
 Acc_angle_x = (atan((Acc_rawY)/sqrt(pow((Acc_rawX),2) + pow((Acc_rawZ),2)))*rad_to_deg) - Acc_angle_error_x;
 /*---Y---*/
 Acc_angle_y = (atan(-1*(Acc_rawX)/sqrt(pow((Acc_rawY),2) + pow((Acc_rawZ),2)))*rad_to_deg) - Acc_angle_error_y;    



  TinyWireM.beginTransmission(0x69);     //begin, Send the slave adress (in this case 68) 
  TinyWireM.write(0x3B);                 //Ask for the 0x3B register- correspond to AcX
  TinyWireM.endTransmission(false);      //keep the transmission and next
  TinyWireM.requestFrom(0x69,6);    //We ask for next 6 registers starting withj the 3B  
  /*We have asked for the 0x3B register. The IMU will send a brust of register.
  * The amount of register to read is specify in the requestFrom function.
  * In this case we request 6 registers. Each value of acceleration is made out of
  * two 8bits registers, low values and high values. For that we request the 6 of them  
  * and just make then sum of each pair. For that we shift to the left the high values 
  * register (<<) and make an or (|) operation to add the low values.
  If we read the datasheet, for a range of+-8g, we have to divide the raw values by 4096*/    
  Acc_rawX2=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ; //each value needs two registres
  Acc_rawY2=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ;
  Acc_rawZ2=(TinyWireM.read()<<8|TinyWireM.read())/4096.0 ; 
 /*Now in order to obtain the Acc angles we use euler formula with acceleration values
 after that we substract the error value found before*/  
 /*---X---*/
 Acc_angle_x2 = (atan((Acc_rawY2)/sqrt(pow((Acc_rawX2),2) + pow((Acc_rawZ2),2)))*rad_to_deg) - Acc_angle_error_x2;
 /*---Y---*/
 Acc_angle_y2 = (atan(-1*(Acc_rawX2)/sqrt(pow((Acc_rawY2),2) + pow((Acc_rawZ2),2)))*rad_to_deg) - Acc_angle_error_y2;    

 
 //////////////////////////////////////Total angle and filter/////////////////////////////////////
 /*---X axis angle---*/
 Total_angle_x = 0.98 *(Total_angle_x + Gyro_angle_x) + 0.02*Acc_angle_x;
 Total_angle_x2 = 0.98 *(Total_angle_x2 + Gyro_angle_x2) + 0.02*Acc_angle_x2;
 /*---Y axis angle---*/
 Total_angle_y = 0.98 *(Total_angle_y + Gyro_angle_y) + 0.02*Acc_angle_y;
 Total_angle_y2 = 0.98 *(Total_angle_y2 + Gyro_angle_y2) + 0.02*Acc_angle_y2;
 
 
// Monitor.println(Total_angle_x);
// Monitor.println(Total_angle_y);
// Monitor.println(Total_angle_x2);
// Monitor.println(Total_angle_y2);

 int knee_angle;
  if( Total_angle_x>90 ){
    if ( Total_angle_x2>90 ){
      knee_angle = 180 - Total_angle_y + Total_angle_y2; 
    }
    else{
      knee_angle = 360 - Total_angle_y - Total_angle_y2; 
    }
  }
  else{
    if ( Total_angle_x2>90 ){
      knee_angle = Total_angle_y + Total_angle_y2; 
    }
    else{
      knee_angle = 180 + Total_angle_y - Total_angle_y2; 
    }
  }
  Monitor.println(knee_angle - 90);

}

Video of the operating system:


10.2.4. Thermistor - 1206

Thermistors are variable resistors that change its resistance based on temperature changes. There are two types of thermistors, which are Negative Temperature Coefficient "NTC" and Positive Temperature Coefficient "PTC". In "NTC" thermistors as temperature increases, resistance decreases. While in "PTC" thermistors as temperature increases, resistance increases. The thermistor I chose to use in this assignment is "1206", which is an "NTC" type.

Basic Connection: connectionThermistor

Since IC circuits can't measure the resistance directly, then we need to measure the voltage and use it to calculate the resistance. Voltage divider rule will be used to calculate the resistance from the voltage point between a known resistor and the thermistor.

voltage_divider

Where Vout is the measured voltage between the known resistor and the thermistor, Vin is the input voltage "5V", R1 is the known resistor value in ohms, and R2 is the variable resistance of thermistor.

This equation can be rearranged to find the variable resistance of thermistor.

equation

Finally, the Steinhart-Hart equation is used to find the temperature from the resistance.

Circuit Design:

Using the skills I gained from Electronics Design week, I have created a simple PCB using "ATtiny44" micro-controller. I used Eagle software to draw the circuit board.

First step, import components libraries that will be used to design the circuit. I used two libraries, which are:

Then, add all components needed and design the circuit schemtic: schematic Click here to download the schematic design file.

Design the actual board by shifting from schematic to PCB, rearrange components and route the circuit.

pcb Click here to download the PCB design file.

Show circuit traces only and export it as PNG image. Thermistor2

Show circuit frame only and export it as PNG image. thermistor_frame3

Generate rml file with Mods:

Use Mods to generate the rml files for traces and frame of the circuit. rml file is sent later to the milling machine becasue it can't understand the PNG image.

Fist, import the traces png file to mods. dpi is shown as 500.024, how ever it should be doubled to 1000.048 to resize it correctly.

resize

Select (1/64) to mill traces image. 64

Set the x,y, and z origins to zero. origins

Click on Calculate to produce the RML file. generate

To generate the frame RML file, repeat the steps but consider inverting the png image and setting mill outline to (1/32). frame_32

Traces rml: traces_rml Click here to download the traces rml file.

Frame rml: frame_rml Click here to download the frame rml file.

Milling:

Send the traces file first to the SRM-20 milling machine and mill it using (1/64) bit. Then, change the milling bit to (1/32) and start milling the outline. You can find more detailed steps about milling in week 5.

milling

Adjust the milling bit to touch the copper sheet surface as shown in the following image: milling2

The following image shows the circuit board after milling the traces: millingTraces

Circuit board after milling the frame: millingFrame

Soldering:

I have gathered all the cirucit components used in the design. The following table list them:

P/NDESC
ATTINY44A-SSU-NDIC MCU 8BIT 4KB FLASH 14SOIC
 THERMISTOR NTC 10KOHM 3750K 1206
 CER RES 20MHZ 15PF SMD
 LED ORANGE CLEAR 1206 SMD
 CAP CER 1UF 50V 10% X7R 1206
 RES SMD 100 OHM 1% 1/4W 1206
 RES SMD 10K OHM 1% 1/4W 1206
 RES SMD 100K OHM 1% 1/4W 1206
 CONN HEADER SMD 6POS 2.54MM
 CONN HEASER SMD 2.54MM

Then I started soldering the components on my circuit board and here is an image of the final result: finalCircuit

Programming:

For programming my circuit, I used Adruino UNO ad programmer. First step to do this is to set Adruino UNO as ISP programmer.

Connect Arduino UNO to laptop USB port through USB cable. serial_bus_1

Click on File > Examples > 11.ArduinoISP > ArduinoISP. serial_bus_2

Set your Board option to Arduino UNO and choose the correct Port. serial_bus_3

Upload the current code. When the code is uploaded, you will get the following message: serial_bus_4

Now, Arduino UNO is ready to be used as a programmer for the ATtiny44 board. Connect ATtiny44 board to Arduino UNO through ISP connector.

AVR ISP 6-pins Header layout:

AVR-ICSP

  • Arduino Pin 13 ---> SCK
  • Arduino Pin 12 ---> MISO
  • Arduino Pin 11 ---> MOSI
  • Arduino Pin 10 ---> RESET
  • Arduino 5V ---> VCC
  • Arduino Ground ---> GND

connectionISP

Set your Board option to ATtiny44 and choose the correct Port. If you don't have the ATtiny44 board shown in the boards list, then you should upload its library to the boards manager (follow steps explained in week 9).

serial_bus_6

Upload the following code, which output the temperature in Celsius to Arduino IDE serial monitor. The output is sent to "PA2" becuase in my ATtiny44 board, thermistor is connected to PA2 (physical pin: 11).

#include "SoftwareSerial.h"
SoftwareSerial Monitor(1, 0);

int Vo;
float R1 = 100000;
float logR2, R2, T;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;
int Tc;

void setup() 
{
  Monitor.begin(9600);
  pinMode(0, OUTPUT);
  pinMode(1, INPUT);
}

void loop() {
  Vo = analogRead(PA2);
  R2 = R1 * (1023.0 / (float)Vo - 1.0);
  logR2 = log(R2);
  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
  Tc = T - 273.15;

  Monitor.println(Tc);
  delay(200);
}

Video of the operating system:


⤧  Next post 11. Applications and Implications ⤧  Previous post 9. Embedded programming