Assignment 13                                          26.4.2017

Topic: Input devices

Measure something: add a sensor to a microcontroller board that you have designed and read it.

Learning outcomes:

Demonstrate workflows used in circuit board design and fabrication.
Implement and interpret programming protocols.

Have you:

Described your design and fabrication process using words/images/screenshots.
Explained the programming process/es you used and how the microcontroller datasheet helped you.
Explained problems and how you fixed them.
Included original design files and code.

A/D conversion (ADC)

Analog-to -digital conversion is totally new thing for me. I was interested to study it and use it in my final project. For example, Attiny44 has 10 bit resolution of ADC and 8 channels. As my final project, I want measure two things, supply voltage (12 V) of my car battery and temperature inside the car.

I designed a simple test board it include two voltage dividers: One use 2x100k resistors to drop voltage from maximum 15 V to Attiny44's measurable level 5 V on ADC pin and then 100k resistor from ADC pin to ground. The second use 10k resistor from 5 V to ADC pin and from there NTC thermistor to ground. NTC type is NAQ103B 375T10. Thus, it's parameters are R25 10 kΩ and B (25/85) 3750. Bridge circuit might be more accurate but voltage divider is enough in my use. I detect only one limit temperature.

I milled this PCB board and put components and wires in place. I measured some basic tests to test the board and understand it's working. Voltage on ADC pin decreases when temperature increases.
adcWires in top side:
Red:  +5 V
White: 0 V

Wires in bottom side:
White: +12 V
Black: ADC 2, voltage

White wire in middle: ADC 1, temperature


















I designed the board so that I can connect it to the output board I made as Assignment 10. Similarly maybe, I need input device connected to main board in my final project. I wrote some code for it. I got some help from page:  https://www.marcelpost.com/wiki/index.php/ATtiny85_ADC. ATTINY44 data sheet advices that by default, the successive approximation circuitry requires an input clock frequency between 50 kHz and 200 kHz to get maximum resolution.

adc




I can select ADC channel by MUX values. ADMUX = 000011b changes it as pin PA3/ADC3.

Prescaler is here 64, therefore sample rate is about 15 kHz for 1 MHz clock. Prescaler should be 16 for 62.5 kHz
sample rate.

I used here 8 bit ADC, therefore the maximum ADC value was 255.

If the ADC value is less than 128, the green led lights and if it is more the red led lights.














Then, I made a finger test. My finger warmed the NTC and led color changes from red to green.

adc 1adc 2

I tested my board with Arduino also. It has also 10 bit ADC. This simple program reads ADC pin and print it out.

arduino adc

t coolt normt warm
Room temperature at 24.3 °C gives ADC value 128 at scale 0-255. Voltage level is 2.57 V.  Outside temperature at 2.4 °C gives ADC value 179 at scale 0-255. Voltage level is 3.54 V.
Warming sauna temperature at 42 °C gives ADC value 95 at scale 0-255. Voltage level is 1.88 V.

Further, I measured following data. Temperature (down) increased from +8 °C to +42 °C. I documented Adc values (left) and voltages (right). The reference voltage was set to VCC, 5.04 V.
chart

Thus, ADC value decreases when temperature increases as planned. The curve is very linear from temperature 8 °C to 26 °C, because I measured only two temperatures there. Between 26 and 42 °C I measured values as 1 to 2 °C steps.

I want measure two channels as my final project and I wrote following code for it.



// FAB_ADC02.c  This code is edited by Yrjo L. for Attiny44 use 2.5.2017
// ====================================
//                                    ATtiny44                        ISP
//                           VCC--+ o     +--GND                MISO---+5V
//    GREEN LED PB0 --+        +--PA0 M2            SCK ---MOSI
//         RED LED PB1 --+        +--PA1 M1            RST ---GND                                            THIS IS NOT THE FINAL CODE FOR FINAL PROJECT
//                     RESET --+        +--PA2 ADC2
//                 INT0 PB2 --+        +--PA3 ADC3 TEMP
//                           PA7 --+        +--SCK ADC4 V-MEA
//                     MOSI --+--------+--MISO
// ====================================
#define F_CPU 1000000UL     // 1 MHz (UL Unsigned Long)
#include <avr/io.h>
#include <util/delay.h>
#define LED_RED PB1           // Define the I/O port to be used for the RED LED.
#define LED_GREEN PB0      // Define the I/O port to be used for the GREEN LED.
// #define MOTOR1 PA1         // Define the I/O port to be used for the MOTOR 1.
// #define MOTOR2 PA0         // Define the I/O port to be used for the MOTOR 2.
void initADC()                         // 8-bit resolution, set ADLAR to 1 to enable the Left-shift result (only bits ADC9..ADC2)
{                                                // then, only reading ADCH is sufficient for 8-bit results (256 values)  
  ADCSRB =    (1 << ADLAR);                                    // left shift result
  ADCSRA =  (1 << ADEN)  |     // Enable ADC
            (1 << ADPS2);                 // Set prescaler to 16. Eg. 1 MHz/16 = 62.5 Hz sample rate.
}
int main(void)
{
    int Mtemp;
    int Mvolt;
    DDRB |= (1 << LED_GREEN);    // LED ports as output
    DDRB |= (1 << LED_RED);       
         initADC();
  while(1) {
     ADMUX =  (1 << MUX1)  | (1 << MUX0);      // use ADC3 (PA3), MUX =000011b = TEMP  
    ADMUX &= ~(1 << MUX2);                             // not use ADC4 (PA4) MUX =000100b = VOLTAGE
    ADCSRA |= (1 << ADSC);                                 // start ADC measurement =TEMP
          while (ADCSRA & (1 << ADSC) );             // wait till conversion complete
    Mtemp = ADCH;
       _delay_ms(2000);
     
   ADMUX &= ~(1 << MUX1)  & ~(1 << MUX0);  // not use ADC3 (PA3), MUX =000011b = TEMP
   ADMUX = (1 << MUX2);                                      // use ADC4 (PA4) MUX =000100b = VOLTAGE
   ADCSRA |= (1 << ADSC);                                     // start ADC measurement  =VOLTAGE
        while (ADCSRA & (1 << ADSC) );                  // wait till conversion complete
  Mvolt = ADCH;
   if (Mtemp < 128 || Mvolt < 200)         // if temperature > 20C or voltage < 12V then pump and blower stop
   {
       PORTB |= (1 << LED_GREEN);   // pump & blower stop
       PORTB &= ~(1 << LED_RED);
       _delay_ms(2000);
       } else {                                            // if temperature < 20C and voltage > 12V then pump and blower work
       PORTB |= (1 << LED_RED);        // pump & blower start
       PORTB &= ~(1 << LED_GREEN);
       _delay_ms(2000);
       }
  }  return(0);
}


It works as expected. If temperature is more than 20 °C or battery voltage is lower than 12 V, then the pump and blower stops and GREEN led lights. Battery voltage level 11.8 V refers to ADC value > 200 and then ADC voltage level is 3.91 V. Voltage level 11.7 V switches RED led on. It refers to to ADC value of < 200 and then ADC voltage level is 3.88 V. Those limits are ideal, however. ADC value of 138 might suit better for temperature limit 20 °C.

ADMUX = 000011b changes pin PA3/ADC3 and ADMUX = 00100b changes pin PA4/ADC4 as the ADC channel.
Prescaler is here 16, therefore sample rate is 62.5 kHz for 1 MHz clock as recommended in data sheet.

Motors 1 and 2 are not yet coded anymore here.

Design files: NTC+15V.sch and CTN+15V.brd.
Code: FAB_ADC02_main.c.
Board as png file: NTC+15VTRC.png.  As replacement of a output file I tested drive outlines by manual control.


Post-registered note:

Later, I made similar voltage dividers for my final project use. Node_F1 board measures temperature and MainB_F1 voltage.

Node_F1
During assignment 15, networking and communication, I made a board for communication but also for testing of temperature measurement (ADC), user interface and serial communication together. My original ADC code needed some modifications to work also in Attiny45. One difference exists as ADLAR set in ADMUX |register for attiny45 and ADCSRB register for Attiny44.
Further, pin PB3 control both the RED led and ADC measurement /ADC2). When it is 1, led lights, and when it is 0, temperature measurement circuit grounds via PB3 and starts. Green led is controlled by pin PB0. I added also a button to test RESET pin feature.

node 02
This schematic is for Node_F1.

I must change pins TX and RX that I can use direct cable between units.













MainB_F1
As well as during final project I made MainB_F1 board as a evolution of boards made during assignment 10 and 13. It is presented below and includes voltage measurement by ADC (ADC7).

main_f1







This schematic is for MainB_F1.

















Boards as png files: fabnode_track02.png and FABcamper21.png.